package com.yxw.live_vod_boot.service.impl;


import com.yxw.live_vod_facade.dto.ShopManagerAddVirtualVisitorDTO;
import com.yxw.live_vod_facade.dto.YxLiveActivityProductsQueryDTO;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.obs.services.ObsClient;
import com.obs.services.model.PutObjectResult;
import com.yxw.live_vod_backend_facade.constant.LiveConstant;
import com.yxw.live_vod_backend_facade.vo.LiveAgreementVO;
import com.yxw.live_vod_boot.cache.QueueCache;
import com.yxw.live_vod_boot.dto.*;
import com.yxw.live_vod_boot.entity.*;
import com.yxw.live_vod_boot.enums.MqttTopicEnum;
import com.yxw.live_vod_boot.feign.BillingSetupServiceClient;
import com.yxw.live_vod_boot.feign.LiveAgreementFeignClient;
import com.yxw.live_vod_boot.mapper.*;
import com.yxw.live_vod_boot.mqtt.MqttGateway;
import com.yxw.live_vod_boot.service.LiveProcessService;
import com.yxw.live_vod_boot.service.ShopService;
import com.yxw.live_vod_boot.utils.*;
import com.yxw.live_vod_boot.vo.CheckLiveIsActiveVO;
import com.yxw.live_vod_boot.vo.LiveOnlineInRedisCacheVO;
import com.yxw.live_vod_facade.constant.LiveShopConstant;
import com.yxw.live_vod_facade.dto.*;
import com.yxw.live_vod_facade.enums.LiveStateEnum;
import com.yxw.live_vod_facade.vo.LivePushServerInforVO;
import com.yxw.live_vod_facade.vo.LivePushStreamRedisCacheVO;
import com.yxw.live_vod_boot.vo.LiveEndShowInforVO;
import com.yxw.live_vod_facade.vo.LiveActivityProductsVO;
import com.yxw.yxnet_cd_center.common.constant.RedisIdConstant;
import com.yxw.yxnet_cd_center.common.dto.BaseUserDTO;
import com.yxw.yxnet_cd_center.common.exception.BaseException;
import com.yxw.yxnet_cd_center.common.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.Map;
import com.yxw.live_vod_boot.vo.LiveInteractiveDataVO;
import com.yxw.live_vod_boot.vo.LiveEndShowTotallInforVO;
import java.util.LinkedHashMap;
import com.yxw.yxnet_cd_center.common.constant.CommonConstant;
import com.yxw.yxnet_cd_center.common.utils.BaseDateTime;
import com.yxw.live_vod_boot.vo.LiveShopUsersVO;
import com.yxw.live_vod_boot.vo.MqttLiveCommentVo;
import com.yxw.live_vod_boot.vo.LiveWatchLogSumVO;
import com.yxw.live_vod_boot.dto.live_comment.LiveInteractiveDataQueryDTO;
import com.yxw.live_vod_boot.dto.ShopManagerEndLiveDTO;
/**
 * 直播处理逻辑服务
 * @author hjx
 * @date 2023-11-17
 */

@Slf4j
@Service
public class LiveProcessServiceImpl implements LiveProcessService{
    
    //缓存延时(秒)
    private static final Long REDIS_CACHE_DELAY_TIME = 600L;
    //推流延时检查中断时间(毫秒)
    private static final Long PUSH_LGOG_TIME_INTERVAL = 90000L;
    //缺省直播时长(秒)
    private static final Integer DEFAULT_LIVE_DURATION = 86400;
    private static final String NOT_LOGIN_ERROR_MSG = "请先登录";
    private static String appName = "";
    private static YxLiveDomainEntity pushDomainEntity = null;
    private static YxLiveDomainEntity liveDomainEntity = null;


    @Autowired
    private HuaWeiObsUtil huaWeiObsUtil;
    
    @Autowired
    private YxLiveShopApplyMapper oYxLiveShopApplyMapper;
    
    @Autowired
    private YxLiveShopUserMapper oYxLiveShopUserMapper;
    
    @Autowired
    private ShopMapper oShopMapper;
    
    @Autowired
    private YxLiveAppMapper oYxLiveAppMapper;
    
    @Autowired
    private YxLiveDomainMapper oYxLiveDomainMapper;
    
    @Autowired
    private YxLiveApplyMapper oYxLiveApplyMapper;
    
    @Autowired
    private YxLiveAddressMapper oYxLiveAddressMapper;

    @Autowired
    private YxLiveActivityProductsMapper oYxLiveActivityProductsMapper;

    @Autowired
    private YxLivePushLogMapper oYxLivePushLogMapper;
    
    @Autowired
    private VideoCoinMapper oVideoCoinMapper;    
    
    @Autowired
    private ShopService oShopService;
    
    @Autowired
    private OrderMapper oOrderMapper;
    
    @Autowired
    private YxLiveWatchLogMapper oYxLiveWatchLogMapper;
    
    @Autowired
    private LiveCommentServiceImpl oLiveCommentServiceImpl;
    
    @Resource
    private LiveAgreementFeignClient oLiveAgreementFeignClient;
    
    @Resource
    private RedisManager oRedisManager;
    
    @Resource
    private BillingSetupServiceClient billingSetupServiceClient;
    
    
    @Resource
    private RedisTemplate redisTemplate;
    
    @Autowired
    private QueueCache oQueueCache;
    
    @Autowired
    private UserMapper oUserMapper;
    
    @Autowired
    private YxLiveCostMapper oYxLiveCostMapper;
    
    @Autowired
    private MqttGateway mqttGateway;    
    /**
     *火山引擎注册的app名称
    
    @Value("${live.app_name}")
    private String appName;
    
     * 火山引擎配置的推流SecretKey
    
    @Value("${live.push_secret_key}")    
    private String pushSecretKey;
   
     * 火山引擎配置的拉流SecretKey
    
    @Value("${live.live_secret_key}")
    private String liveSecretKey;
     */

  
    
    /**
     * 店铺开通直播权限
     * @param oLiveShopAddApplyDTO
     * @return BaseResult
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult shopSendApply(HttpServletRequest httpRequest,MultipartFile defaultHomePicture,LiveShopAddApplyDTO oLiveShopAddApplyDTO)
    {        
        if(StrUtil.isBlank(oLiveShopAddApplyDTO.getCreateUserId()))
        {
            return BaseResult.failed("createUserId不能为空");
        }
        if(null == oLiveShopAddApplyDTO.getLiveShopId())
        {
            return BaseResult.failed("liveShopId不能为空");
        }
        if(StrUtil.isBlank(oLiveShopAddApplyDTO.getRemark()))
        {
            return BaseResult.failed("个性签名remark不能为空");
        }  
      
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }
        if(!oLiveShopAddApplyDTO.getCreateUserId().equals(oBaseUserDTO.getUserId()))
        {
            return BaseResult.failed("没有操作权限");
        }
        
        YxLiveShopApplyEntity oYxLiveShopApplyEntity;
        QueryWrapper<YxLiveShopApplyEntity> oShopApplyQueryWrapper = new QueryWrapper();
        oShopApplyQueryWrapper.eq("live_shop_id",oLiveShopAddApplyDTO.getLiveShopId());
        //oShopApplyQueryWrapper.ne("audit_result",2);
        oYxLiveShopApplyEntity = oYxLiveShopApplyMapper.selectOne(oShopApplyQueryWrapper);
        if(null != oYxLiveShopApplyEntity)
        {
            return BaseResult.success(oYxLiveShopApplyEntity);
        }
        
        YxSysUserEntity oYxSysUserEntity = oUserMapper.selectById(oLiveShopAddApplyDTO.getCreateUserId());
        if(null == oYxSysUserEntity)
        {
            return BaseResult.failed("createUserId对应的用户不存在");
        } 
        
        QueryWrapper<YxLiveShopEntity> oYxLiveShopQueryWrapper = new QueryWrapper();
        oYxLiveShopQueryWrapper.eq("live_shop_id",oLiveShopAddApplyDTO.getLiveShopId());
        YxLiveShopEntity oYxLiveShopEntity = oShopMapper.selectOne(oYxLiveShopQueryWrapper);
        if(null == oYxLiveShopEntity)
        {
            return BaseResult.failed("Id对应的店铺不存在");
        } 
        //把创建者设置为默认播主
        YxLiveShopUserEntity oYxLiveShopUserEntity = new YxLiveShopUserEntity();
        oYxLiveShopUserEntity.setCreateTime(BaseDateTime.getDate());
        oYxLiveShopUserEntity.setCreateUserId(oLiveShopAddApplyDTO.getCreateUserId());
        oYxLiveShopUserEntity.setLiveShopId(oLiveShopAddApplyDTO.getLiveShopId());
        oYxLiveShopUserEntity.setShopId(oYxLiveShopEntity.getShopId());
        oYxLiveShopUserEntity.setShopUserId(oLiveShopAddApplyDTO.getCreateUserId());
        oYxLiveShopUserEntity.setShopUserName(oYxSysUserEntity.getUserName());
        oYxLiveShopUserEntity.setUserTelephoneNumber(oYxSysUserEntity.getPhone());
        oYxLiveShopUserEntity.setHeadUrl(oYxSysUserEntity.getHeadUrl());
        oYxLiveShopUserEntity.setUserType(0);
        QueryWrapper<YxLiveShopUserEntity> oShopUserQueryWrapper = new QueryWrapper();
        oShopUserQueryWrapper.eq("live_shop_id",oYxLiveShopUserEntity.getLiveShopId());
        oShopUserQueryWrapper.eq("shop_user_id",oYxLiveShopUserEntity.getShopUserId());
        int iUserCount = oYxLiveShopUserMapper.selectCount(oShopUserQueryWrapper);
       
        //开通直播权限的申请
        oYxLiveShopApplyEntity = new YxLiveShopApplyEntity();
        oYxLiveShopApplyEntity.setAuditResult(2);
        oYxLiveShopApplyEntity.setCreateUserId(oLiveShopAddApplyDTO.getCreateUserId());
        oYxLiveShopApplyEntity.setLiveShopId(oLiveShopAddApplyDTO.getLiveShopId());
        oYxLiveShopApplyEntity.setShopName(oYxLiveShopEntity.getShopName());
        oYxLiveShopApplyEntity.setShopId(oYxLiveShopEntity.getShopId());
        oYxLiveShopApplyEntity.setChannelCode(oYxLiveShopEntity.getChannelCode());
        oYxLiveShopApplyEntity.setMerchantId(oYxLiveShopEntity.getMerchantId());
        oYxLiveShopApplyEntity.setMerchantName(oYxLiveShopEntity.getMerchantName());
        oYxLiveShopApplyEntity.setMaxLive(1);
        oYxLiveShopApplyEntity.setCreateTime(BaseDateTime.getDate());
        oYxLiveShopApplyEntity.setUpdateTime(oYxLiveShopApplyEntity.getCreateTime());
        String liveHomePictureKey = "";
        if(!defaultHomePicture.isEmpty())
        {
            String obsDownloadUrlStartPoint = huaWeiObsUtil.getObsDownloadUrlStartPointNoEndSlash();
            //liveHomePictureKey = FileClassifyEnum.SHOP_FILE.getPath() + BaseDateTime.getShortDateStringNoSlipt() + "/" + UUID.randomUUID().toString().replace("-", "") + defaultHomePicture.getOriginalFilename().substring(defaultHomePicture.getOriginalFilename().lastIndexOf(CommonConstant.POINT));
            liveHomePictureKey = UUID.randomUUID().toString().replace("-", "") + defaultHomePicture.getOriginalFilename().substring(defaultHomePicture.getOriginalFilename().lastIndexOf(CommonConstant.POINT));
            if(liveHomePictureKey.startsWith("/"))
            {
                oYxLiveShopEntity.setShopBackground(obsDownloadUrlStartPoint.concat(liveHomePictureKey));
            }
            else
            {
                oYxLiveShopEntity.setShopBackground(obsDownloadUrlStartPoint.concat("/").concat(liveHomePictureKey));
            }
        }
        oYxLiveShopEntity.setSign(oLiveShopAddApplyDTO.getRemark());
        oYxLiveShopEntity.setUpdateTime(oYxLiveShopApplyEntity.getCreateTime());
        oShopMapper.updateById(oYxLiveShopEntity);
        oYxLiveShopApplyMapper.insert(oYxLiveShopApplyEntity);

        if(iUserCount<1){
            oYxLiveShopUserMapper.insert(oYxLiveShopUserEntity);
            String key = LiveShopConstant.LIVE_SHOP_USER_REDISKEY_PREFIX.concat(oYxLiveShopUserEntity.getLiveShopId().toString());
            oRedisManager.setMapValue(key,oYxLiveShopUserEntity.getShopUserId() ,oYxLiveShopUserEntity);
        } 
        PermissionShopDTO shopDTO = new PermissionShopDTO();
        shopDTO.setShopId(oYxLiveShopEntity.getLiveShopId());
        oShopService.permissionShop(shopDTO);
        if (!defaultHomePicture.isEmpty() || oLiveShopAddApplyDTO.getRemark() != null) {
            ShopBackgroundReviewDTO dto = new ShopBackgroundReviewDTO();
            UploadHomepageDTO homepageDTO = new UploadHomepageDTO();
            homepageDTO.setSign(oLiveShopAddApplyDTO.getRemark());
            homepageDTO.setShopId(oYxLiveShopEntity.getLiveShopId());
            dto.setHomepageDTO(homepageDTO);
            dto.setBackgroundKey(liveHomePictureKey);
            dto.setBackgroundPath(oYxLiveShopEntity.getShopBackground());
            dto.setBackgroundFile(defaultHomePicture);
            oShopService.addShopHomePageReview(dto);
        }        
        if(!defaultHomePicture.isEmpty())
        {
            //主页背景图上传华为云            
            try
            {  
                PutObjectResult oPutObjectResult = huaWeiObsUtil.uploadStream(liveHomePictureKey, defaultHomePicture.getInputStream());
                log.error("主页背景图oPutObjectResult.getStatusCode()：" + oPutObjectResult.getStatusCode());
            }
            catch (Exception e)
            {  
                log.error("主页背景图上传异常："+e.getMessage());
                throw new BaseException("主页背景图上传异常："+e.getMessage());
            } 
        }
        return BaseResult.success(oYxLiveShopApplyEntity);
    }
    /*** 
    * 根据店铺Id查询是否开通直播申请
    * @param oYxLiveShopApplyDTO
    * @return BaseResult
    **/
    @Override
    public BaseResult shopQuryApplyByLiveShopId(Long liveShopId)
    {
        YxLiveShopApplyEntity oYxLiveShopApplyEntity;
        QueryWrapper<YxLiveShopApplyEntity> oShopApplyQueryWrapper = new QueryWrapper();
        oShopApplyQueryWrapper.eq("live_shop_id",liveShopId);
        oYxLiveShopApplyEntity = oYxLiveShopApplyMapper.selectOne(oShopApplyQueryWrapper);
        if(null != oYxLiveShopApplyEntity)
        {
            return BaseResult.success(oYxLiveShopApplyEntity);
        }
        else
        {
            return BaseResult.failed("还没开通直播权限");
        }
    }

    /**
     * 店铺添加店员
     * @param oYxLiveShopUserDTO
     * @return BaseResult
     */ 
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult addShopUser(HttpServletRequest httpRequest,LiveShopAddUserDTO oYxLiveShopUserDTO)
    {
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }
        if(!oYxLiveShopUserDTO.getCreateUserId().equals(oBaseUserDTO.getUserId()))
        {
            return BaseResult.failed("没有操作权限");
        }
        QueryWrapper<YxLiveShopEntity> oYxLiveShopQueryWrapper = new QueryWrapper();
        oYxLiveShopQueryWrapper.eq("live_shop_id",oYxLiveShopUserDTO.getLiveShopId());
        YxLiveShopEntity oYxLiveShopEntity = oShopMapper.selectOne(oYxLiveShopQueryWrapper);
        if(null == oYxLiveShopEntity)
        {
            return BaseResult.failed("Id对应的店铺不存在");
        }         
        QueryWrapper<YxLiveShopUserEntity> oYxLiveShopUserQueryWrapper = new QueryWrapper();
        oYxLiveShopUserQueryWrapper.eq("live_shop_id",oYxLiveShopUserDTO.getLiveShopId());
        oYxLiveShopUserQueryWrapper.eq("shop_user_id",oYxLiveShopUserDTO.getCreateUserId());
        if(oYxLiveShopUserMapper.selectCount(oYxLiveShopUserQueryWrapper)<1)
        {
            return BaseResult.failed("200", "没有操作权限");
        } 
        oYxLiveShopUserQueryWrapper = new QueryWrapper();
        oYxLiveShopUserQueryWrapper.eq("live_shop_id",oYxLiveShopUserDTO.getLiveShopId());
        oYxLiveShopUserQueryWrapper.eq("shop_user_id",oYxLiveShopUserDTO.getShopUserId());
        YxLiveShopUserEntity oYxLiveShopUserEntity = oYxLiveShopUserMapper.selectOne(oYxLiveShopUserQueryWrapper);
        if(null != oYxLiveShopUserEntity)
        {
            return BaseResult.failed("200", "用户已存在，不用再添加");
        }        
        oYxLiveShopUserEntity = new YxLiveShopUserEntity();
        BeanUtil.copyProperties(oYxLiveShopUserDTO, oYxLiveShopUserEntity);
        oYxLiveShopUserEntity.setCreateTime(BaseDateTime.getDate());
        oYxLiveShopUserEntity.setUpdateTime(BaseDateTime.getDate());
        oYxLiveShopUserMapper.insert(oYxLiveShopUserEntity);
        String key = LiveShopConstant.LIVE_SHOP_USER_REDISKEY_PREFIX.concat(oYxLiveShopEntity.getLiveShopId().toString());
        oRedisManager.setMapValue(key,oYxLiveShopUserEntity.getShopUserId(), oYxLiveShopUserEntity);
        return BaseResult.success(oYxLiveShopUserEntity);
    }
    /**
     * 店铺修改店员
     * @param oLiveShopEditUserDTO
     * @return BaseResult
     */
    @Override
    public BaseResult editShopUser(HttpServletRequest httpRequest,LiveShopEditUserDTO oLiveShopEditUserDTO)
    {
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }
        YxLiveShopUserEntity oYxLiveShopUserEntity = oYxLiveShopUserMapper.selectById(oLiveShopEditUserDTO.getShopUserId());
        if(null == oYxLiveShopUserEntity)
        {
            return BaseResult.failed("200", "需要修改的用户不存在");
        } 

        QueryWrapper<YxLiveShopUserEntity> oYxLiveShopUserQueryWrapper = new QueryWrapper();
        oYxLiveShopUserQueryWrapper.eq("live_shop_id",oYxLiveShopUserEntity.getLiveShopId());
        oYxLiveShopUserQueryWrapper.eq("shop_user_id",oBaseUserDTO.getUserId());
        if(oYxLiveShopUserMapper.selectCount(oYxLiveShopUserQueryWrapper)<1)
        {
            return BaseResult.failed("200", "不是店铺员工,没有操作权限");
        }   
        oYxLiveShopUserEntity.setUpdateTime(BaseDateTime.getDate());
        oYxLiveShopUserEntity.setUserType(oLiveShopEditUserDTO.getUserType());
        oYxLiveShopUserMapper.updateById(oYxLiveShopUserEntity);
        String key = LiveShopConstant.LIVE_SHOP_USER_REDISKEY_PREFIX.concat(oYxLiveShopUserEntity.getLiveShopId().toString());
        oRedisManager.setMapValue(key,oYxLiveShopUserEntity.getShopUserId(),oYxLiveShopUserEntity);        
        return BaseResult.success(oYxLiveShopUserEntity);
    }
    /**
     * 店铺删除店员
     * @param oShopDeleteUserDTO
     * @return BaseResult
     */
    @Override
    public BaseResult deleteShopUser(HttpServletRequest httpRequest,LiveShopDeleteUserDTO oShopDeleteUserDTO)
    {
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }
        if(!oShopDeleteUserDTO.getOperateUserId().equals(oBaseUserDTO.getUserId()))
        {
            return BaseResult.failed("没有操作权限");
        }
        QueryWrapper<YxLiveShopUserEntity> oYxLiveShopUserQueryWrapper = new QueryWrapper();
        oYxLiveShopUserQueryWrapper.eq("live_shop_id",oShopDeleteUserDTO.getLiveShopId());
        List<YxLiveShopUserEntity> userList = oYxLiveShopUserMapper.selectList(oYxLiveShopUserQueryWrapper);
        if(userList.isEmpty())
        {
            return BaseResult.failed("所选店铺没有员工");
        }
        int iOperateCount = 0;
        YxLiveShopUserEntity oYxLiveShopUserEntity = null;
        for(YxLiveShopUserEntity oneYxLiveShopUserEntity : userList)
        {
            if(oneYxLiveShopUserEntity.getShopUserId().equals(oShopDeleteUserDTO.getOperateUserId()))
            {
                iOperateCount = iOperateCount + 1;
            }
            if(oneYxLiveShopUserEntity.getShopUserId().equals(oShopDeleteUserDTO.getShopUserId()))
            {
                oYxLiveShopUserEntity = oneYxLiveShopUserEntity;
            }
        }
        if(iOperateCount<1)
        {
            return BaseResult.failed("200", "没有操作权限");
        }
        if(null == oYxLiveShopUserEntity)
        {
            return BaseResult.failed("需要删除的用户不存在");
        }
        oYxLiveShopUserMapper.deleteById(oYxLiveShopUserEntity.getId());
        String key = LiveShopConstant.LIVE_SHOP_USER_REDISKEY_PREFIX.concat(oYxLiveShopUserEntity.getLiveShopId().toString());
        oRedisManager.delMapValue(key,oYxLiveShopUserEntity.getShopUserId());
        return BaseResult.success();
    }
    /*** 
    * 自定义查询开通直播的店铺员工表
    * @param oYxLiveShopUserDTO
    * @return List<YxLiveShopUserEntity>
    **/
    @Override
    public List<YxLiveShopUserEntity> selectYxLiveShopUserList(Long liveShopId)
    {
        QueryWrapper<YxLiveShopUserEntity> oYxLiveShopUserQueryWrapper = new QueryWrapper();

        oYxLiveShopUserQueryWrapper.eq("live_shop_id",liveShopId);
        //List<YxLiveShopUserEntity> oListYxLiveShopUser = oYxLiveShopUserMapper.selectList(oYxLiveShopUserQueryWrapper);
        //return Res.ok(oListYxLiveShopUser);
        return  oYxLiveShopUserMapper.selectList(oYxLiveShopUserQueryWrapper);
    }
    /*** 
    * 自定义查询开通直播的店铺员工表
    * @param liveShopId
    * @return List<YxLiveShopUserEntity>
    **/
    @Override
    public List<LiveShopUsersVO> getLiveShopOnlineUsers(Long liveShopId,String liveId)
    {
        List<LiveShopUsersVO> list = new ArrayList();
        String redisKey = LiveShopConstant.LIVE_SHOP_USER_REDISKEY_PREFIX.concat(liveShopId.toString());
        LinkedHashMap shopUserHashMap = (LinkedHashMap)oRedisManager.getMap(redisKey);
        redisKey = LiveShopConstant.LIVE_SHOP_ONLINE_USERMAP_REDISKEY_PREFIX.concat(liveId);
        LinkedHashMap onlineUserHashMap = (LinkedHashMap)oRedisManager.getMap(redisKey);
        if(!shopUserHashMap.isEmpty() && !onlineUserHashMap.isEmpty())
        {            
            shopUserHashMap.forEach((k,v)->{
                Object oObject = onlineUserHashMap.get(k);
                YxLiveShopUserEntity oYxLiveShopUserEntity = (YxLiveShopUserEntity)v;
                LiveShopUsersVO oLiveShopUsersVO = new LiveShopUsersVO();
                oLiveShopUsersVO.setId(oYxLiveShopUserEntity.getId());
                oLiveShopUsersVO.setHeadUrl(oYxLiveShopUserEntity.getHeadUrl());
                oLiveShopUsersVO.setLiveShopId(oYxLiveShopUserEntity.getLiveShopId());
                oLiveShopUsersVO.setShopId(oYxLiveShopUserEntity.getShopId());
                oLiveShopUsersVO.setShopUserId(oYxLiveShopUserEntity.getShopUserId());
                oLiveShopUsersVO.setShopUserName(oYxLiveShopUserEntity.getShopUserName());
                oLiveShopUsersVO.setUserType(oYxLiveShopUserEntity.getUserType());
                if(null != oObject)
                {
                    oLiveShopUsersVO.setUserState(1);
                }
                else
                {
                    oLiveShopUsersVO.setUserState(0);
                }
                list.add(oLiveShopUsersVO);
            });
        }
        return list;
    }
    /**
     * 店铺发送直播申请
     * @param oShopSendLiveApplyDTO
     * @return BaseResult
     */ 
    @Override 
    @Transactional(rollbackFor = Exception.class)
    public BaseResult shopSendLiveApply(HttpServletRequest httpRequest,Long liveShopId)
    {
        //ShopSendLiveApplyDTO oShopSendLiveApplyDTO

        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }
        String userId = oBaseUserDTO.getUserId();
        //if(!oShopSendLiveApplyDTO.getUserId().equals(oBaseUserDTO.getUserId()))
        //{
        //    return BaseResult.failed("没有操作权限");
        //}        
        BaseResult ratioBaseResult = billingSetupServiceClient.getFeeDeductRatio();
        Integer iRatio = 0;
        if(ratioBaseResult.isResult())
        {
            iRatio = (Integer)ratioBaseResult.getData();
        }
        else
        {
            return BaseResult.failed("200", "获取兑换率失败");
        }
        if(iRatio<1)
        {
            return BaseResult.failed("200", "兑换率不能小于1");
        }
        QueryWrapper<YxLiveShopUserEntity> oYxLiveShopUserQueryWrapper = new QueryWrapper();
        oYxLiveShopUserQueryWrapper.eq("live_shop_id",liveShopId);
        oYxLiveShopUserQueryWrapper.eq("shop_user_id",userId);
        YxLiveShopUserEntity oYxLiveShopUserEntity = oYxLiveShopUserMapper.selectOne(oYxLiveShopUserQueryWrapper);
        if(null == oYxLiveShopUserEntity)
        {
            return BaseResult.failed("200", "不是店铺员工,没有操作权限");
        } 
        YxLiveShopApplyEntity oYxLiveShopApplyEntity = getLiveShopApply(liveShopId);
        if(null == oYxLiveShopApplyEntity)
        {
            return BaseResult.failed("200","请先开通直播权限");
        }
        //QueryWrapper<YxLiveShopEntity> oYxLiveShopQueryWrapper = new QueryWrapper();
        //oYxLiveShopQueryWrapper.eq("shop_id",oShopSendLiveApplyDTO.getShopId());
        YxLiveShopEntity oYxLiveShopEntity = oShopMapper.selectById(liveShopId);
        if(null == oYxLiveShopEntity)
        {
            return BaseResult.failed("200", "Id对应的店铺不存在");
        }
        if(null != oYxLiveShopEntity.getLiveCoin())
        {
            if(oYxLiveShopEntity.getLiveCoin().intValue() < iRatio)
            {
                return BaseResult.failed("200","店铺的视频币(" + oYxLiveShopEntity.getLiveCoin() + ")即将耗尽，请先充值");
            }
        }
        if(oYxLiveShopEntity.getShopState() == 0)
        {
            return BaseResult.failed("200","店铺被禁止直播，请先申述解禁");
        }
        if(oYxLiveShopEntity.getShopState() == 1)
        {
            return BaseResult.failed("200","店铺被中断直播，请稍后再试");
        }
       
        String appName = getDefaultAppName();
        if(appName.equals(""))
        {
            return BaseResult.failed("200","平台还没有配置appName");
        }
        YxLiveDomainEntity pushYxLiveDomainEntity = getPushDomain();        
        if(null == pushYxLiveDomainEntity)
        {
            return BaseResult.failed("200","平台还没有配置推流域名");
        }
        if(StrUtil.isBlank(pushYxLiveDomainEntity.getDomainName()))
        {
            return BaseResult.failed("200","平台配置推流域名信息时没有配置域名关键字");
        }
        if(StrUtil.isBlank(pushYxLiveDomainEntity.getSecretKey()))
        {
            return BaseResult.failed("200","平台配置推流域名信息时没有配置密钥关键字");
        }
        YxLiveDomainEntity liveDomainEntity = getLiveDomain();
        if(null == liveDomainEntity)
        {
            return BaseResult.failed("200","平台还没有配置拉流域名");
        }
        if(StrUtil.isBlank(liveDomainEntity.getDomainName()))
        {
            return BaseResult.failed("200","平台配置拉流域名信息时没有配置域名关键字");
        }
        if(StrUtil.isBlank(liveDomainEntity.getSecretKey()))
        {
            return BaseResult.failed("200","平台配置拉流域名信息时没有配置密钥关键字");
        }
        YxLiveApplyEntity oYxLiveApplyEntity = getLiveApply(liveShopId);
        if(null != oYxLiveApplyEntity)
        {
            return BaseResult.success(oYxLiveApplyEntity);
        }
        oYxLiveApplyEntity = new YxLiveApplyEntity();
        Long volcStartTime = System.currentTimeMillis();
        Long volcEndTime = 0l;
        Long volcEndTimeTmp = 0l;
        //BeanUtil.copyProperties(oShopSendLiveApplyDTO, oYxLiveApplyEntity);
        oYxLiveApplyEntity.setShopApplyId(oYxLiveShopApplyEntity.getId());
        oYxLiveApplyEntity.setCreateTime(BaseDateTime.getDate());
        oYxLiveApplyEntity.setUpdateTime(BaseDateTime.getDate());
        oYxLiveApplyEntity.setCreateUserId(userId);
        oYxLiveApplyEntity.setId(UUID.randomUUID().toString().replaceAll("-", ""));
        oYxLiveApplyEntity.setLiveShopId(oYxLiveShopEntity.getLiveShopId());
        oYxLiveApplyEntity.setShopId(oYxLiveShopEntity.getShopId());
        oYxLiveApplyEntity.setChannelCode(oYxLiveShopEntity.getChannelCode());
        oYxLiveApplyEntity.setLiveState(0);
        //剩余的钱可以兑换多少时间（分钟）
        Integer iTime = oYxLiveShopEntity.getLiveCoin().intValue() / iRatio;
        iTime = iTime * 60;
        Integer volcTime =  0;
        if(iTime > DEFAULT_LIVE_DURATION)
        {
            volcTime = DEFAULT_LIVE_DURATION;
        }
        else
        {
            volcTime =  iTime;
        }
        volcEndTime = volcStartTime/1000 + volcTime;
        volcEndTimeTmp = volcTime * 1000 + volcStartTime;
        oYxLiveApplyEntity.setLiveStartTime(volcStartTime);
        oYxLiveApplyEntity.setLiveEndTime(volcEndTimeTmp);
        YxLiveAddressEntity oYxLiveAddressEntity = new YxLiveAddressEntity();
        oYxLiveAddressEntity.setId(UUID.randomUUID().toString().replaceAll("-", ""));
        oYxLiveAddressEntity.setLiveAppName(appName);
        oYxLiveAddressEntity.setCreateUserId(userId);
        oYxLiveAddressEntity.setShopUserId(userId);
        oYxLiveAddressEntity.setShopUserName(oYxLiveShopUserEntity.getShopUserName());
        oYxLiveAddressEntity.setLiveShopId(oYxLiveShopEntity.getLiveShopId());
        oYxLiveAddressEntity.setShopId(oYxLiveShopEntity.getShopId());
        //oYxLiveAddressEntity.setLiveApplyState(iTime);
        oYxLiveAddressEntity.setLiveValuation(volcTime * iRatio);
        String  streamName = oYxLiveShopEntity.getShopId() + "_" + volcEndTime + "_" + UUID.randomUUID().toString().replaceAll("-", "");
        String sign = PasswordUtil.md5Hex("/" + appName + "/" + streamName + pushYxLiveDomainEntity.getSecretKey() + volcEndTime);
        //rtmp://yx-push.yxjt.vip/{AppName}/{StreamName}?{鉴权信息}
        //String pushUrl = "rtmp://" + pushYxLiveDomainEntity.getDomainName() + "/" + appName + "/" + streamName + "?volcTime=" + volcEndTime + "&volcSecret=" + sign;
        String Url = "rtmp://" + pushYxLiveDomainEntity.getDomainName() + "/" + appName + "/" + streamName;
        oYxLiveAddressEntity.setPushUrl(Url);
        oYxLiveAddressEntity.setPushAuth( "volcTime=" + volcEndTime + "&volcSecret=" + sign);
        sign = PasswordUtil.md5Hex("/" + appName + "/" + streamName + liveDomainEntity.getSecretKey() + volcEndTime);
        if(liveDomainEntity.getNeedSsl() == 0)
        {
            Url = "http://" + liveDomainEntity.getDomainName() + "/" + appName + "/" + streamName + ".m3u8?volcTime=" + volcEndTime + "&volcSecret=" + sign;
        }
        else
        {
            Url = "https://" + liveDomainEntity.getDomainName() + "/" + appName + "/" + streamName + ".m3u8?volcTime=" + volcEndTime + "&volcSecret=" + sign;
        }
        oYxLiveAddressEntity.setLiveUrl(Url);
        oYxLiveAddressEntity.setLiveStreamName(streamName);
        oYxLiveAddressEntity.setCreateTime(oYxLiveApplyEntity.getCreateTime());
        oYxLiveAddressEntity.setLiveAppName(appName);
        oYxLiveAddressEntity.setShopId(oYxLiveApplyEntity.getShopId());
        oYxLiveAddressEntity.setLiveShopId(oYxLiveShopEntity.getLiveShopId());
        oYxLiveAddressEntity.setLiveStartTime(volcStartTime);
        //volcTime = volcTime * 1000;
        volcStartTime = volcTime * 1000 + volcStartTime ;
        oYxLiveAddressEntity.setLiveEndTime(volcStartTime);
        oYxLiveApplyEntity.setLiveAddressId(oYxLiveAddressEntity.getId());
        oYxLiveAddressEntity.setApplyId(oYxLiveApplyEntity.getId());
        oYxLiveAddressEntity.setLiveState(0);
        oYxLiveAddressEntity.setLiveTag(oYxLiveShopEntity.getShopName());
        oYxLiveAddressEntity.setLivePicture(oYxLiveShopEntity.getShopAvatar());
        oYxLiveApplyMapper.insert(oYxLiveApplyEntity);
        oYxLiveAddressMapper.insert(oYxLiveAddressEntity);            
        ArrayList<RedisPipeAccessObject> pipeList = new ArrayList();
        RedisPipeAccessObject oRedisPipeAccessObject;
        volcTime = volcTime + REDIS_CACHE_DELAY_TIME.intValue();
        oRedisPipeAccessObject = RedisPipeAccessObject.getAddObject(LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(oYxLiveApplyEntity.getId()), oYxLiveApplyEntity, volcTime);
        pipeList.add(oRedisPipeAccessObject);
        oRedisPipeAccessObject = RedisPipeAccessObject.getAddObject(LiveShopConstant.LIVE_ADDRESS_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()), oYxLiveAddressEntity, volcTime);
        pipeList.add(oRedisPipeAccessObject);
        oRedisPipeAccessObject = RedisPipeAccessObject.getAddObject(LiveShopConstant.LIVE_SHOP_ONLINE_USER_COUNT_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()), 0L, volcTime);
        pipeList.add(oRedisPipeAccessObject);
        oRedisPipeAccessObject = RedisPipeAccessObject.getAddObject(LiveShopConstant.LIVE_SHOP_ONLINE_USER_MAX_COUNT_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()), 0L, volcTime);
        pipeList.add(oRedisPipeAccessObject);
        oRedisPipeAccessObject = RedisPipeAccessObject.getAddObject(LiveShopConstant.LIVE_SHOP_VISIT_TOTAL_USER_COUNT_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()), 0L, volcTime);
        pipeList.add(oRedisPipeAccessObject);
        oRedisPipeAccessObject = RedisPipeAccessObject.getAddObject(LiveShopConstant.LIVE_SHOP_LIVE_TOTAL_WATCH_DURATION_LENGHT_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()), 0L, volcTime);
        pipeList.add(oRedisPipeAccessObject);
        oRedisPipeAccessObject = RedisPipeAccessObject.getAddObject(LiveShopConstant.LIVE_SHOP_LIVE_TOTAL_WATCH_STREAM_LENGHT_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()), 0L, volcTime);
        pipeList.add(oRedisPipeAccessObject);
        oRedisPipeAccessObject = RedisPipeAccessObject.getAddObject(LiveShopConstant.LIVE_SHOP_ORDER_TOTAL_COUNT_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()), 0L, volcTime);
        pipeList.add(oRedisPipeAccessObject);
        oRedisPipeAccessObject = RedisPipeAccessObject.getAddObject(LiveShopConstant.LIVE_SHOP_ORDER_TOTAL_FEE_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()), 0L, volcTime);
        pipeList.add(oRedisPipeAccessObject);
        //HashMap oLiveShopUserHashMap = new HashMap();
        //oRedisPipeAccessObject = RedisPipeAccessObject.getAddMapObject(LiveShopConstant.LIVE_SHOP_VISIT_MAP_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()), oLiveShopUserHashMap, volcTime);
        //pipeList.add(oRedisPipeAccessObject);
        //ConcurrentHashMap<String,YxLiveWatchLogAddDTO> oLiveWatchLogHashMap = new ConcurrentHashMap();
        //oRedisPipeAccessObject = RedisPipeAccessObject.getAddMapObject(LiveShopConstant.LIVE_SHOP_USER_WATCHLOG_HASHMAP_PREFIX.concat(oYxLiveAddressEntity.getId()), oLiveWatchLogHashMap, volcTime);
        pipeList.add(oRedisPipeAccessObject);
        oRedisManager.multiAccessByPipe(pipeList);
        return BaseResult.success(oYxLiveApplyEntity);
    }
    
    /**
     * 店铺修改直播间图片
     * @param defaultHomePicture
     * @param shopApplyId
     * @return BaseResult
     */  
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult shopUserEditLiveApplyPicture(HttpServletRequest httpRequest,MultipartFile defaultHomePicture,String liveApplyId)
    {
        
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }
        if(defaultHomePicture.isEmpty())
        {
            return BaseResult.failed("200", "图片不能为空");
        }
        YxLiveApplyEntity oYxLiveApplyEntity = oYxLiveApplyMapper.selectById(liveApplyId);
        if(null == oYxLiveApplyEntity)
        {
            return BaseResult.failed("找不到对应申请信息");
        } 
        Long applyEndTime = oYxLiveApplyEntity.getLiveEndTime() - System.currentTimeMillis();
        if(applyEndTime < 1000)
        {
            oYxLiveApplyEntity.setLiveState(LiveStateEnum.LIVE_END.getCode());
            UpdateWrapper<YxLiveApplyEntity> oUpdateLiveApplyWrapper = new UpdateWrapper();
            oUpdateLiveApplyWrapper.eq("apply_id", oYxLiveApplyEntity.getId());
            oUpdateLiveApplyWrapper.set("live_state", LiveStateEnum.LIVE_END.getCode());      
            oYxLiveApplyMapper.update(null, oUpdateLiveApplyWrapper);
            oYxLiveApplyEntity.setLiveState(LiveStateEnum.LIVE_END.getCode());
            UpdateWrapper<YxLiveAddressEntity> oUpdateLiveAddressWrapper = new UpdateWrapper();
            oUpdateLiveAddressWrapper.eq("live_id", oYxLiveApplyEntity.getLiveAddressId());
            oUpdateLiveAddressWrapper.set("live_state", LiveStateEnum.LIVE_END.getCode());      
            oYxLiveAddressMapper.update(null, oUpdateLiveAddressWrapper);
            return BaseResult.failed("直播申请的有效时间结束，请重新申请");
        }
        String obsDownloadUrlStartPoint = huaWeiObsUtil.getObsDownloadUrlStartPointNoEndSlash();
        applyEndTime = applyEndTime/1000 + REDIS_CACHE_DELAY_TIME;        
        QueryWrapper<YxLiveShopUserEntity> oYxLiveShopUserQueryWrapper = new QueryWrapper();
        oYxLiveShopUserQueryWrapper.eq("live_shop_id",oYxLiveApplyEntity.getLiveShopId());
        oYxLiveShopUserQueryWrapper.eq("shop_user_id",oBaseUserDTO.getUserId());
        if(oYxLiveShopUserMapper.selectCount(oYxLiveShopUserQueryWrapper)<1)
        {
            return BaseResult.failed("200", "没有操作权限");
        }
        String liveHomePicture = oYxLiveApplyEntity.getLiveHomePicture();
        if(StrUtil.isNotBlank(liveHomePicture))
        {
            liveHomePicture = liveHomePicture.replaceAll(obsDownloadUrlStartPoint, "");
        }
        String liveHomePictureKey = "";
        //liveHomePictureKey = FileClassifyEnum.LIVE_FILE.getPath() + BaseDateTime.getShortDateStringNoSlipt() + "/" + UUID.randomUUID().toString().replace("-", "") + defaultHomePicture.getOriginalFilename().substring(defaultHomePicture.getOriginalFilename().lastIndexOf(CommonConstant.POINT));
        liveHomePictureKey = UUID.randomUUID().toString().replace("-", "") + defaultHomePicture.getOriginalFilename().substring(defaultHomePicture.getOriginalFilename().lastIndexOf(CommonConstant.POINT));
        if(liveHomePictureKey.startsWith("/"))
        {
            oYxLiveApplyEntity.setLiveHomePicture(obsDownloadUrlStartPoint.concat(liveHomePictureKey));
        }
        else
        {
            oYxLiveApplyEntity.setLiveHomePicture(obsDownloadUrlStartPoint.concat("/").concat(liveHomePictureKey));
        }
        oYxLiveApplyEntity.setUpdateTime(BaseDateTime.getDate());
        oYxLiveApplyMapper.updateById(oYxLiveApplyEntity);
        
        //YxLiveShopApplyEntity oYxLiveShopApplyEntity
        UpdateWrapper<YxLiveShopApplyEntity> oShopApplyUpdateWrapper = new UpdateWrapper();
        oShopApplyUpdateWrapper.eq("shop_apply_id", oYxLiveApplyEntity.getShopApplyId());
        oShopApplyUpdateWrapper.set("live_home_picture", oYxLiveApplyEntity.getLiveHomePicture());
        int i = oYxLiveShopApplyMapper.update(null, oShopApplyUpdateWrapper);
        if(i != 1)
        {
            throw new BaseException("修改该数据失败");
        }
        //直播间图片上传华为云   
        ObsClient oObsClient = huaWeiObsUtil.getObsClient();
        try
        {  
            PutObjectResult oPutObjectResult = huaWeiObsUtil.uploadStreamNotClose(oObsClient,liveHomePictureKey, defaultHomePicture.getInputStream());
            log.error("直播间图片oPutObjectResult.getStatusCode()：" + oPutObjectResult.getStatusCode());
        }
        catch (Exception e)
        {  
            try
            {  
                oObsClient.close();
            }
            catch (Exception ee)
            {              
                log.error("直播间图片上传，关闭客户端异常："+ee.getMessage());            
            } 
            log.error("直播间图片上传异常："+e.getMessage());
            throw new BaseException("直播间图片上传异常："+e.getMessage());
        } 
        //如果存在老图片从华为云上则删除
        if(StrUtil.isNotBlank(liveHomePicture))
        {
            huaWeiObsUtil.deleteFileNotClose(oObsClient, liveHomePicture);
        }
        try
        {  
            oObsClient.close();
        }
        catch (Exception ee)
        {              
            log.error("直播间图片传异常："+ee.getMessage());            
        }         
        String redisKey = LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(oYxLiveApplyEntity.getId());
        oRedisManager.set(redisKey, oYxLiveApplyEntity,applyEndTime);
        return BaseResult.success();
    }    
    /**
     * 店铺修改直播间信息
     * @param oLiveUserEditShopDTO
     * @return BaseResult
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult shopUserEditShopApply(HttpServletRequest httpRequest,ShopUserEditLiveApplyDTO oShopUserEditLiveApplyDTO)
    {
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }
        YxLiveApplyEntity oYxLiveApplyEntity = oYxLiveApplyMapper.selectById(oShopUserEditLiveApplyDTO.getLiveApplyId());
        if(null == oYxLiveApplyEntity)
        {
            return BaseResult.failed("找不到对应申请信息");
        }  
        Long applyEndTime = oYxLiveApplyEntity.getLiveEndTime() - System.currentTimeMillis();
        if(applyEndTime < 1000)
        {
            oYxLiveApplyEntity.setLiveState(LiveStateEnum.LIVE_END.getCode());
            UpdateWrapper<YxLiveApplyEntity> oUpdateLiveApplyWrapper = new UpdateWrapper();
            oUpdateLiveApplyWrapper.eq("apply_id", oYxLiveApplyEntity.getId());
            oUpdateLiveApplyWrapper.set("live_state", LiveStateEnum.LIVE_END.getCode());      
            oYxLiveApplyMapper.update(null, oUpdateLiveApplyWrapper);
            oYxLiveApplyEntity.setLiveState(LiveStateEnum.LIVE_END.getCode());
            UpdateWrapper<YxLiveAddressEntity> oUpdateLiveAddressWrapper = new UpdateWrapper();
            oUpdateLiveAddressWrapper.eq("live_id", oYxLiveApplyEntity.getLiveAddressId());
            oUpdateLiveAddressWrapper.set("live_state", LiveStateEnum.LIVE_END.getCode());      
            oYxLiveAddressMapper.update(null, oUpdateLiveAddressWrapper);
            return BaseResult.failed("直播申请的有效时间结束，请重新申请");
        }
        applyEndTime = applyEndTime/1000 + REDIS_CACHE_DELAY_TIME;        
        YxLiveShopApplyEntity oYxLiveShopApplyEntity = oYxLiveShopApplyMapper.selectById(oYxLiveApplyEntity.getShopApplyId());
        if(null == oYxLiveShopApplyEntity)
        {
            return BaseResult.failed("Id对应的申请不存在");
        }       
        QueryWrapper<YxLiveShopUserEntity> oYxLiveShopUserQueryWrapper = new QueryWrapper();
        oYxLiveShopUserQueryWrapper.eq("live_shop_id",oYxLiveShopApplyEntity.getLiveShopId());
        oYxLiveShopUserQueryWrapper.eq("shop_user_id",oBaseUserDTO.getUserId());
        if(oYxLiveShopUserMapper.selectCount(oYxLiveShopUserQueryWrapper)<1)
        {
            return BaseResult.failed("没有操作权限");
        }
 
        int columCounter = 0;
        UpdateWrapper<YxLiveApplyEntity> oLiveApplyUpdateWrapper = new UpdateWrapper();
        UpdateWrapper<YxLiveShopApplyEntity> oShopApplyUpdateWrapper = new UpdateWrapper();
        oShopApplyUpdateWrapper.eq("shop_apply_id", oYxLiveShopApplyEntity.getId());
        oLiveApplyUpdateWrapper.eq("apply_id", oYxLiveApplyEntity.getId());
        if(StrUtil.isNotBlank(oShopUserEditLiveApplyDTO.getLiveHomeName()))
        {
            oLiveApplyUpdateWrapper.set("live_home_name", oShopUserEditLiveApplyDTO.getLiveHomeName());
            oShopApplyUpdateWrapper.set("live_home_name", oShopUserEditLiveApplyDTO.getLiveHomeName());
            oYxLiveApplyEntity.setLiveHomeName(oShopUserEditLiveApplyDTO.getLiveHomeName());
            oYxLiveShopApplyEntity.setLiveHomeName(oShopUserEditLiveApplyDTO.getLiveHomeName());
            columCounter = columCounter + 1;
        }
        if(StrUtil.isNotBlank(oShopUserEditLiveApplyDTO.getLiveWelcomeWords()))
        {
            oLiveApplyUpdateWrapper.set("live_welcome_words", oShopUserEditLiveApplyDTO.getLiveWelcomeWords());
            oShopApplyUpdateWrapper.set("live_welcome_words", oShopUserEditLiveApplyDTO.getLiveWelcomeWords());
            oYxLiveApplyEntity.setLiveWelcomeWords(oShopUserEditLiveApplyDTO.getLiveWelcomeWords());
            oYxLiveShopApplyEntity.setLiveWelcomeWords(oShopUserEditLiveApplyDTO.getLiveWelcomeWords());
            columCounter = columCounter + 1;
        }
        if(StrUtil.isNotBlank(oShopUserEditLiveApplyDTO.getLiveEndWords()))
        {
            oLiveApplyUpdateWrapper.set("live_end_words", oShopUserEditLiveApplyDTO.getLiveEndWords());
            oShopApplyUpdateWrapper.set("live_end_words", oShopUserEditLiveApplyDTO.getLiveEndWords());
            oYxLiveApplyEntity.setLiveEndWords(oShopUserEditLiveApplyDTO.getLiveEndWords());
            oYxLiveShopApplyEntity.setLiveEndWords(oShopUserEditLiveApplyDTO.getLiveEndWords());
            columCounter = columCounter + 1;
        }
        if(columCounter < 1)
        {
            return BaseResult.failed("必须要修改部分内容");
        }
        oLiveApplyUpdateWrapper.set("update_time", BaseDateTime.getDate());
        oYxLiveShopApplyMapper.update(null, oShopApplyUpdateWrapper);
        oYxLiveApplyMapper.update(null, oLiveApplyUpdateWrapper);
        String redisKey = LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(oYxLiveApplyEntity.getId());
        oRedisManager.set(redisKey, oYxLiveApplyEntity,applyEndTime);
        return BaseResult.success();    
    }    
    
    /**
     * 店铺客户端发送开始推流/开始直播
     * @param 
     * @return BaseResult
     */ 
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult clientSendStartPushApply(HttpServletRequest httpRequest,ClientSendStartPushApplyDTO oClientSendStartPushApplyDTO)
    {
        String token = httpRequest.getHeader("token");
        if(StrUtil.isBlank(token))
        {
            token = "";
        }
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }  
        YxLiveApplyEntity oYxLiveApplyEntity = null;//(YxLiveApplyEntity)oRedisManager.get(LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(oClientSendStartPushApplyDTO.getApplyId()));
        Object oObject = null;
        oObject = oRedisManager.get(LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(oClientSendStartPushApplyDTO.getApplyId()));
        //YxLiveApplyEntity oYxLiveApplyEntity =  oYxLiveApplyMapper.selectById(oClientSendStartPushApplyDTO.getApplyId());
        if(null != oObject)
        {
            oYxLiveApplyEntity = (YxLiveApplyEntity)oObject;
        }
        if(null == oYxLiveApplyEntity)
        {
            return BaseResult.failed("200","找不到对应的直播申请");
        }
        long iTime = oYxLiveApplyEntity.getLiveEndTime() - System.currentTimeMillis();
        if(iTime < 0)
        {
            return BaseResult.failed("200","直播申请已过期");
        }
        
        //YxLiveAddressEntity oYxLiveAddressEntity = oYxLiveAddressMapper.selectById(oYxLiveApplyEntity.getLiveAddressId());
        YxLiveAddressEntity oYxLiveAddressEntity = null;//(YxLiveAddressEntity)oRedisManager.get(LiveShopConstant.LIVE_ADDRESS_REDISKEY_PREFIX.concat(oYxLiveApplyEntity.getLiveAddressId()));
        oObject = oRedisManager.get(LiveShopConstant.LIVE_ADDRESS_REDISKEY_PREFIX.concat(oYxLiveApplyEntity.getLiveAddressId()));
        if(null != oObject)
        {
            oYxLiveAddressEntity = (YxLiveAddressEntity)oObject;
        }
        if(null == oYxLiveAddressEntity)
        {
            return BaseResult.failed("200","找不到对应的直播地址");
        } 
        
        LiveOnlineInRedisCacheVO oLiveOnlineInRedisCacheVO = oYxLiveAddressEntity.ToLiveOnlineInRedisCacheVO();
        oLiveOnlineInRedisCacheVO.setLiveHomeName(oYxLiveApplyEntity.getLiveHomeName());
        oLiveOnlineInRedisCacheVO.setLiveWelcomeWords(oYxLiveApplyEntity.getLiveWelcomeWords());
        oLiveOnlineInRedisCacheVO.setLiveEndWords(oYxLiveApplyEntity.getLiveEndWords());
        oLiveOnlineInRedisCacheVO.setLivePicture(oYxLiveApplyEntity.getLiveHomePicture());
        oLiveOnlineInRedisCacheVO.setShopName(oYxLiveAddressEntity.getLiveTag());
        oLiveOnlineInRedisCacheVO.setShopAvatar(oYxLiveAddressEntity.getLivePicture());
        QueryWrapper<YxLiveActivityProductsEntity> oActivityProductsQueryWrapper = new QueryWrapper();
        //oActivityProductsQueryWrapper.eq("shop_id",oYxLiveApplyEntity.getShopId());
        oActivityProductsQueryWrapper.eq("live_id",oYxLiveApplyEntity.getLiveAddressId());
        oActivityProductsQueryWrapper.orderByAsc("product_order");
        //直播小黄车商品缓存
        List<YxLiveActivityProductsEntity> oProductList = oYxLiveActivityProductsMapper.selectList(oActivityProductsQueryWrapper);        
        oYxLiveAddressEntity.setPushStartServerTime(System.currentTimeMillis());
        oYxLiveAddressEntity.setPushStartTime(oClientSendStartPushApplyDTO.getPushStartTime());
        oYxLiveAddressEntity.setUpdateTime(BaseDateTime.getDate());
        oYxLiveAddressEntity.setLiveState(LiveStateEnum.LIVE_ONLINE.getCode());
        oYxLiveApplyEntity.setLiveState(LiveStateEnum.LIVE_ONLINE.getCode());
        oYxLiveAddressMapper.updateById(oYxLiveAddressEntity);
        oYxLiveApplyMapper.updateById(oYxLiveApplyEntity);
        String redisKey = LiveShopConstant.LIVE_PUSH_STREAM_CACHE_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId());
        LivePushStreamRedisCacheVO oLivePushStreamRedisCacheVO = null;//(LivePushStreamRedisCacheVO)oRedisManager.get(redisKey);
        Object oObjectLivePushStreamRedisCacheVO = oRedisManager.get(redisKey);
        if(null != oObjectLivePushStreamRedisCacheVO)
        {
            oLivePushStreamRedisCacheVO = (LivePushStreamRedisCacheVO)oObjectLivePushStreamRedisCacheVO;
        }
        //开播前删除意外存在的在线直播缓存列表
        Object oObjectLiveOnlineInRedisCache = oRedisManager.getMapValue(LiveShopConstant.LIVE_SHOP_ONLINELIVE_SHOPIDKEY_HASH_REDISKEY, oYxLiveApplyEntity.getLiveShopId().toString());
        
        LiveOnlineInRedisCacheVO oLiveOnlineInRedisCacheVOTmp = null;// (LiveOnlineInRedisCacheVO)
        if(null != oObjectLiveOnlineInRedisCache)
        {
            oLiveOnlineInRedisCacheVOTmp = (LiveOnlineInRedisCacheVO)oObjectLiveOnlineInRedisCache;
        }
        if(null != oLiveOnlineInRedisCacheVOTmp)
        {
            if(!oLiveOnlineInRedisCacheVOTmp.getLiveId().equals(oYxLiveAddressEntity.getId()))
            {
                oRedisManager.delMapValue(LiveShopConstant.LIVE_SHOP_ONLINELIVE_HASH_REDISKEY, oLiveOnlineInRedisCacheVOTmp.getLiveId());
            }
        }
        //推流缓存信息
        String redisLivePushStreamKey = LiveShopConstant.LIVE_PUSH_STREAM_CACHE_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId());
        if(null == oLivePushStreamRedisCacheVO)
        {
            oLivePushStreamRedisCacheVO = new LivePushStreamRedisCacheVO();
            oLivePushStreamRedisCacheVO.setApplyId(oClientSendStartPushApplyDTO.getApplyId());
            oLivePushStreamRedisCacheVO.setLiveId(oYxLiveAddressEntity.getId());
            oLivePushStreamRedisCacheVO.setLiveStartTime(oYxLiveApplyEntity.getLiveStartTime());
            oLivePushStreamRedisCacheVO.setLiveEndTime(oYxLiveApplyEntity.getLiveEndTime());
            oLivePushStreamRedisCacheVO.setInterruptedCount(0);
            //oLivePushStreamRedisCacheVO.setLiveState(1);
            oLivePushStreamRedisCacheVO.setPushLogCount(0);
            oLivePushStreamRedisCacheVO.setLastPushLogClientTime(0L);
            oLivePushStreamRedisCacheVO.setLastPushLogTime(0L);
            oLivePushStreamRedisCacheVO.setPushLogStartClientTime(0L);
            oLivePushStreamRedisCacheVO.setPushLogStartTime(0L);
            oLivePushStreamRedisCacheVO.setTotallPushDuration(0L);
            oLivePushStreamRedisCacheVO.setTotallPushLength(0L);
            oLivePushStreamRedisCacheVO.setShopId(oYxLiveApplyEntity.getShopId());
            oLivePushStreamRedisCacheVO.setLiveShopId(oYxLiveApplyEntity.getLiveShopId());
            oLivePushStreamRedisCacheVO.setPushUserId(oBaseUserDTO.getUserId());
        }
        //else
        //{
        //    oLivePushStreamRedisCacheVO.setLiveState(1);
        //}
        final LivePushStreamRedisCacheVO tmpLivePushStreamRedisCacheVO = oLivePushStreamRedisCacheVO;
        final YxLiveApplyEntity applyTmp = oYxLiveApplyEntity;
        final YxLiveAddressEntity addressTmp = oYxLiveAddressEntity;
        redisTemplate.executePipelined((RedisCallback<Object>) new RedisCallback<Object>()
        {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException
            {
                connection.openPipeline();
                try
                {
                    long iTimeTmp = applyTmp.getLiveEndTime() - System.currentTimeMillis();
                    iTimeTmp = iTimeTmp/1000 + REDIS_CACHE_DELAY_TIME;
                    //直播推流缓存
                    String redisKey = LiveShopConstant.LIVE_PUSH_STREAM_CACHE_REDISKEY_PREFIX.concat(addressTmp.getId());
                    connection.set(redisTemplate.getKeySerializer().serialize(redisKey),redisTemplate.getValueSerializer().serialize(tmpLivePushStreamRedisCacheVO));
                    connection.expire(redisTemplate.getKeySerializer().serialize(redisKey), iTimeTmp);
                    //直播申请缓存  设置状态值
                    redisKey = LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(oClientSendStartPushApplyDTO.getApplyId());
                    connection.set(redisTemplate.getKeySerializer().serialize(redisKey),redisTemplate.getValueSerializer().serialize(applyTmp));
                    connection.expire(redisTemplate.getKeySerializer().serialize(redisKey), iTimeTmp);
                    //直播地址缓存  设置状态值
                    redisKey = LiveShopConstant.LIVE_ADDRESS_REDISKEY_PREFIX.concat(addressTmp.getId());
                    connection.set(redisTemplate.getKeySerializer().serialize(redisKey),redisTemplate.getValueSerializer().serialize(addressTmp));
                    connection.expire(redisTemplate.getKeySerializer().serialize(redisKey), iTimeTmp);
                    //直播小黄车商品缓存
                    if(!oProductList.isEmpty())
                    {
                        for(YxLiveActivityProductsEntity oYxLiveActivityProductsEntity : oProductList)
                        {
                            redisKey = LiveShopConstant.LIVE_SHOP_PRODUCT_REDISKEY_PREFIX.concat(addressTmp.getId());
                            connection.hSet(redisTemplate.getKeySerializer().serialize(redisKey), redisTemplate.getHashKeySerializer().serialize(oYxLiveActivityProductsEntity.getId().toString()), redisTemplate.getHashValueSerializer().serialize(oYxLiveActivityProductsEntity.ConvertToLiveActivityProductsVO()));
                        }
                        connection.expire(redisTemplate.getKeySerializer().serialize(redisKey), iTimeTmp);
                    }
                    //在线直播缓存
                    //redisKey = LiveShopConstant.LIVE_SHOP_ONLINELIVE_HASH_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getLiveShopId().toString());
                    redisKey = LiveShopConstant.LIVE_SHOP_ONLINELIVE_HASH_REDISKEY;
                    connection.hSet(redisTemplate.getKeySerializer().serialize(redisKey),redisTemplate.getHashKeySerializer().serialize(addressTmp.getId()),redisTemplate.getHashValueSerializer().serialize(oLiveOnlineInRedisCacheVO));
                    redisKey = LiveShopConstant.LIVE_SHOP_ONLINELIVE_SHOPIDKEY_HASH_REDISKEY;
                    connection.hSet(redisTemplate.getKeySerializer().serialize(redisKey),redisTemplate.getHashKeySerializer().serialize(addressTmp.getLiveShopId().toString()),redisTemplate.getHashValueSerializer().serialize(oLiveOnlineInRedisCacheVO));
                    connection.set(redisTemplate.getKeySerializer().serialize(LiveShopConstant.LIVE_SHOP_ONLINELIVE_STATE_CHECK_PREFIX.concat(addressTmp.getId())),redisTemplate.getValueSerializer().serialize(LiveStateEnum.LIVE_END.getCode()));
                    //oRedisManager.set(LiveShopConstant.LIVE_SHOP_ONLINELIVE_STATE_CHECK_PREFIX.concat(oYxLivePushLogDTO.getLiveId()), LiveStateEnum.LIVE_ONLINE.getCode());
                }
                catch(SerializationException e)
                {
                    log.error("clientSendStartPushApply  redisTemplate.executePipelined命令异常:====================================>{}", e);
                    throw new BaseException("clientSendStartPushApply redisTemplate.executePipelined命令异常:"+e.getMessage());
                }
                finally
                {
                    connection.close();
                }
                return null;
            }
        });  

        //推流时加延时计费任务
        String mapKey = LiveShopConstant.LIVE_PUSH_STREAM_CACHE_REDISKEY_PREFIX + "_" + UUID.randomUUID().toString().replaceAll("-", "");
        CheckLiveIsActiveVO oCheckLiveIsActiveVO = new CheckLiveIsActiveVO();
        oCheckLiveIsActiveVO.InIt(redisLivePushStreamKey,mapKey,oYxLiveAddressEntity.getLiveEndTime(),1);
        oCheckLiveIsActiveVO.setExecCount(0);
        oQueueCache.delayCheckLiveIsActivePut(oCheckLiveIsActiveVO);    
        String aesKey;
        token = oClientSendStartPushApplyDTO.getUserId().trim() + token.trim();
        if(token.length()<16)
        {
            aesKey = String.format("%016d", token);
        }
        else
        {
            aesKey = token.substring(0, 16);
        }
        LivePushServerInforVO oLivePushServerInforVO = new LivePushServerInforVO();
        oLivePushServerInforVO.setPushURL(oYxLiveAddressEntity.getPushUrl());
        oLivePushServerInforVO.setPushSecret(Aes128.Aes128EncryptUtf8(aesKey,oYxLiveAddressEntity.getPushAuth()).getData().toString());
        return BaseResult.success(oLivePushServerInforVO);
    }
    /**
     * 店铺客户端根据推流地址开始推流
     * @param 
     * @return BaseResult
     */ 
    @Override
    public BaseResult clientSendPushLog(HttpServletRequest httpRequest,YxLivePushLogDTO oYxLivePushLogDTO)
    {
        Long delayTime = System.currentTimeMillis();
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }
        YxLiveShopUserEntity oYxLiveShopUserEntity = getYxLiveShopUserEntity(oYxLivePushLogDTO.getLiveShopId(),oBaseUserDTO.getUserId());
        if(null == oYxLiveShopUserEntity)
        {
            return BaseResult.failed("用户不存在");
        }

        YxLivePushLogEntity oYxLivePushLogEntity = new YxLivePushLogEntity();
        BeanUtil.copyProperties(oYxLivePushLogDTO, oYxLivePushLogEntity);
        oYxLivePushLogEntity.setPushIp(httpRequest.getRemoteAddr());
        Long iDuration = oYxLivePushLogEntity.getPushEndTime() - oYxLivePushLogEntity.getPushStartTime();
        oYxLivePushLogEntity.setTotallDuration(iDuration.intValue());
        oYxLivePushLogMapper.insert(oYxLivePushLogEntity); 
        String redisKey = LiveShopConstant.LIVE_PUSH_STREAM_CACHE_REDISKEY_PREFIX.concat(oYxLivePushLogDTO.getLiveId());
        Object oObject = null;
        oObject = oRedisManager.get(redisKey);
        LivePushStreamRedisCacheVO oLivePushStreamRedisCacheVO = null;//(LivePushStreamRedisCacheVO)oRedisManager.get(redisKey);
        if(null != oObject)
        {
            oLivePushStreamRedisCacheVO = (LivePushStreamRedisCacheVO)oObject;
        }
        if(null != oLivePushStreamRedisCacheVO)
        {
            //90秒后延时检查是否更新
            if(oLivePushStreamRedisCacheVO.getPushLogCount() == 0)
            {
                oLivePushStreamRedisCacheVO.setPushLogStartTime(delayTime);
                oLivePushStreamRedisCacheVO.setPushLogStartClientTime(oYxLivePushLogDTO.getPushStartTime());
            }
            oLivePushStreamRedisCacheVO.setPushLogCount(oLivePushStreamRedisCacheVO.getPushLogCount() + 1);
            oLivePushStreamRedisCacheVO.setLastPushLogTime(delayTime);
            if(oYxLivePushLogDTO.getPushEndTime().compareTo(oLivePushStreamRedisCacheVO.getLastPushLogClientTime())>0)
            {
                oLivePushStreamRedisCacheVO.setLastPushLogClientTime(oYxLivePushLogDTO.getPushEndTime());
            }
            oLivePushStreamRedisCacheVO.setTotallPushDuration(oLivePushStreamRedisCacheVO.getTotallPushDuration() + iDuration);
            oLivePushStreamRedisCacheVO.setTotallPushLength(oLivePushStreamRedisCacheVO.getTotallPushLength() + oYxLivePushLogDTO.getStreamTotallLength());
            //oLivePushStreamRedisCacheVO.setLiveState(1);        
            oRedisManager.set(redisKey, oLivePushStreamRedisCacheVO);
            //redisKey = LiveShopConstant.LIVE_SHOP_ONLINELIVE_STATE_CHECK_PREFIX.concat(oYxLivePushLogDTO.getLiveId());
            oRedisManager.set(LiveShopConstant.LIVE_SHOP_ONLINELIVE_STATE_CHECK_PREFIX.concat(oYxLivePushLogDTO.getLiveId()), LiveStateEnum.LIVE_ONLINE.getCode());
            //redisKey = redisKey = LiveShopConstant.LIVE_PUSH_STREAM_CACHE_REDISKEY_PREFIX.concat(oYxLivePushLogDTO.getLiveId());
            delayTime = delayTime + PUSH_LGOG_TIME_INTERVAL;
            String mapKey = redisKey + "_" + UUID.randomUUID().toString().replaceAll("-", "");
            CheckLiveIsActiveVO oCheckLiveIsActiveVO = new CheckLiveIsActiveVO();
            oCheckLiveIsActiveVO.InIt(redisKey,mapKey,delayTime,0);
            oQueueCache.delayCheckLiveIsActivePut(oCheckLiveIsActiveVO);
            
        }
        
        
        return BaseResult.success(oYxLivePushLogEntity);  
    }
    /**
     * 店铺客户端发送结束推流申请
     * @param 
     * @return BaseResult
     */ 
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult<LiveEndShowInforVO> clientSendEndPushApply(HttpServletRequest httpRequest,final String liveId)
    {
        String redisKey = LiveShopConstant.LIVE_PUSH_STREAM_CACHE_REDISKEY_PREFIX.concat(liveId);
        LivePushStreamRedisCacheVO oLivePushStreamRedisCacheVO = (LivePushStreamRedisCacheVO)oRedisManager.get(redisKey);
        if(null == oLivePushStreamRedisCacheVO)
        {
            return BaseResult.failed("从Redis缓存中找不到对应缓存数据,key=" + redisKey);
        }
        //YxLiveAddressEntity oYxLiveAddressEntity =  oYxLiveAddressMapper.selectById(liveId); 
        redisKey = LiveShopConstant.LIVE_ADDRESS_REDISKEY_PREFIX.concat(liveId);
        YxLiveAddressEntity oYxLiveAddressEntity = (YxLiveAddressEntity)oRedisManager.get(redisKey);
        if(null == oYxLiveAddressEntity)
        {
            return BaseResult.failed("200", "Id对应的直播不存在");
        } 
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }
        YxLiveShopUserEntity oYxLiveShopUserEntity = getYxLiveShopUserEntity(oYxLiveAddressEntity.getLiveShopId(),oBaseUserDTO.getUserId());
        if(null == oYxLiveShopUserEntity)
        {
            return BaseResult.failed("用户不存在");
        }
        if(!oYxLiveShopUserEntity.getLiveShopId().equals(oYxLiveAddressEntity.getLiveShopId()))
        {
            return BaseResult.failed("200", "不是店铺员工,没有操作权限");
        }
        BaseResult ratioBaseResult = billingSetupServiceClient.getFeeDeductRatio();
        Integer iRatio = 0;
        if(ratioBaseResult.isResult())
        {
            iRatio = (Integer)ratioBaseResult.getData();
        }
        else
        {
            return BaseResult.failed("200", "获取兑换率失败");
        }
        if(iRatio<1)
        {
            return BaseResult.failed("200", "兑换率不能小于1");
        } 
        redisKey = LiveShopConstant.LIVE_SHOP_VISIT_TOTAL_USERMAP_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId());
        LinkedHashMap oTotallUsersLinkedHashMap = (LinkedHashMap)oRedisManager.getMap(redisKey);
        Long totallWatchUserCount = 0L;
        Long totallWatchCount = 0L;
        Long watchDuration = 0L;
        Long watchStreamLen = 0L;
        Long orderCount = 0L;
        Long orderTotallFee = 0L;
        Long maxOnlineUsersCount = 0L;
        Long expireTime = System.currentTimeMillis() - oYxLiveAddressEntity.getLiveEndTime()+ REDIS_CACHE_DELAY_TIME.intValue();
        List<String> redisKeys = new java.util.ArrayList(); 
        
        redisKeys.add(LiveShopConstant.LIVE_SHOP_VISIT_TOTAL_USER_COUNT_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()));
        redisKeys.add(LiveShopConstant.LIVE_SHOP_LIVE_TOTAL_WATCH_DURATION_LENGHT_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()));
        redisKeys.add(LiveShopConstant.LIVE_SHOP_LIVE_TOTAL_WATCH_STREAM_LENGHT_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()));
        redisKeys.add(LiveShopConstant.LIVE_SHOP_ORDER_TOTAL_COUNT_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()));
        redisKeys.add(LiveShopConstant.LIVE_SHOP_ORDER_TOTAL_FEE_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId())); 
        redisKeys.add(LiveShopConstant.LIVE_SHOP_ONLINE_USER_MAX_COUNT_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()));
        List<Object> oList = oRedisManager.multiGet(redisKeys);
        if(null != oList)
        {
            totallWatchCount = Long.valueOf(String.valueOf(oList.get(0)));
            watchDuration = Long.valueOf(String.valueOf(oList.get(1)));
            watchStreamLen = Long.valueOf(String.valueOf(oList.get(2)));
            orderCount = Long.valueOf(String.valueOf(oList.get(3)));
            orderTotallFee = Long.valueOf(String.valueOf(oList.get(4)));
            maxOnlineUsersCount = Long.valueOf(String.valueOf(oList.get(5)));
        }
        if(null != oTotallUsersLinkedHashMap)
        {
            totallWatchUserCount = Long.valueOf(oTotallUsersLinkedHashMap.size());
        }
        oYxLiveAddressEntity.setPushStartServerTime(oLivePushStreamRedisCacheVO.getPushLogStartTime());
        oYxLiveAddressEntity.setPushEndServerTime(oLivePushStreamRedisCacheVO.getLastPushLogTime());
        oYxLiveAddressEntity.setPushStartTime(oLivePushStreamRedisCacheVO.getPushLogStartClientTime());
        oYxLiveAddressEntity.setPushEndTime(oLivePushStreamRedisCacheVO.getLastPushLogClientTime());
        oYxLiveAddressEntity.setLiveState(LiveStateEnum.LIVE_END.getCode());
        Integer liveFee;
        oYxLiveAddressEntity.setLiveTotallDuration(oLivePushStreamRedisCacheVO.getTotallPushDuration()/1000);
        liveFee = oYxLiveAddressEntity.getLiveTotallDuration().intValue()/iRatio/60;
        oYxLiveAddressEntity.setLiveFees(liveFee);
        oYxLiveAddressEntity.setLiveTotallPushLength(oLivePushStreamRedisCacheVO.getTotallPushLength());
        oYxLiveAddressEntity.setLiveOrderCount(orderCount.intValue());
        oYxLiveAddressEntity.setLiveOrderTotalFee(new BigDecimal(orderTotallFee));
        //oYxLiveAddressEntity.setWatchDuration(watchDuration);
        oYxLiveAddressEntity.setWatchStreamLength(watchStreamLen);
        oYxLiveAddressEntity.setWatchUserCount(totallWatchUserCount);
        oYxLiveAddressEntity.setWatchNumber(totallWatchCount);
        oYxLiveAddressEntity.setMaxOnlineUserCount(maxOnlineUsersCount);        
        LiveEndShowTotallInforVO oLiveEndShowTotallInforVO = getLiveEndShowTotallInfor(oYxLiveAddressEntity);
        oYxLiveAddressEntity.setWatchDuration(oLiveEndShowTotallInforVO.getWatchDuration());
        oYxLiveAddressEntity.setAveragWatchDuration(oLiveEndShowTotallInforVO.getAveragWatchDuration());
        oYxLiveAddressEntity.setWatchUserPayRate(oLiveEndShowTotallInforVO.getWatchUserPayRate());
        oYxLiveAddressEntity.setAddedFansNumber(oLiveEndShowTotallInforVO.getAddedFansNumber());
        oYxLiveAddressEntity.setCommentNumber(oLiveEndShowTotallInforVO.getCommentNumber());
        oYxLiveAddressEntity.setCommentUserNumber(oLiveEndShowTotallInforVO.getCommentUserNumber());
        oYxLiveAddressEntity.setLikeNumber(oLiveEndShowTotallInforVO.getLikeNumber());        
        oYxLiveAddressEntity.setUpdateTime(BaseDateTime.getDate());
        oYxLiveAddressEntity.setProductNumber(oLiveEndShowTotallInforVO.getProductNumber());
        //    LiveLogSumVO oLiveLogSumVO = oYxLivePushLogMapper.getLiveLogSum(liveId);
        //    oYxLiveAddressEntity.setLiveTotallDuration(oLiveLogSumVO.getLiveTotallDuration());
        //    oYxLiveAddressEntity.setLiveTotallPushLength(oLiveLogSumVO.getLiveStreamTotallLength());
        YxLiveShopEntity oYxLiveShopEntity = oShopMapper.selectById(oYxLiveAddressEntity.getLiveShopId());
        Integer feeRemainder = oYxLiveShopEntity.getLiveCoin().intValue()-liveFee;
        oYxLiveShopEntity.setLiveCoin(new BigDecimal(feeRemainder));
        oYxLiveShopEntity.setUpdateTime(BaseDateTime.getDate());
        YxVideoCoinEntity oYxVideoCoinEntity = new YxVideoCoinEntity();
        oYxVideoCoinEntity.setAmount("-" + liveFee);
        
        oYxVideoCoinEntity.setShopName(oYxLiveShopEntity.getShopName());
        oYxVideoCoinEntity.setShopId(oYxLiveShopEntity.getLiveShopId());
        oYxVideoCoinEntity.setShopkeeperId(oYxLiveShopEntity.getUserId());
        oYxVideoCoinEntity.setShopkeeperName(oYxLiveShopEntity.getUserName());
        oYxVideoCoinEntity.setType(0);
        oYxVideoCoinEntity.setDetail("直播 " + BaseDateTime.getLongDateTimeString(oYxLiveAddressEntity.getLiveEndTime()));
        oYxVideoCoinEntity.setTradingTime(BaseDateTime.getDate());
        oYxVideoCoinEntity.setTransactionNum(IdWorkerUtils.generateTransactionNumber());
        oYxVideoCoinEntity.setStatus(0);
        YxLiveCostEntity oYxLiveCostEntity = new YxLiveCostEntity();
        oYxLiveCostEntity.setStartTime(BaseDateTime.getDate(oLivePushStreamRedisCacheVO.getPushLogStartTime()));
        oYxLiveCostEntity.setEndTime(BaseDateTime.getDate(oLivePushStreamRedisCacheVO.getLastPushLogTime()));
        oYxLiveCostEntity.setLiveId(liveId);
        oYxLiveCostEntity.setShopId(oYxLiveAddressEntity.getLiveShopId());
        oYxLiveCostEntity.setTotalTime(oLivePushStreamRedisCacheVO.getTotallPushDuration().toString());
        oYxLiveCostEntity.setExpendVideoCoin(liveFee);
        oYxLiveCostEntity.setExpenditureTime(BaseDateTime.getDate());
        UpdateWrapper<YxLiveApplyEntity> oLiveApplyUpdateWrapper = new UpdateWrapper();
        oLiveApplyUpdateWrapper.eq("apply_id", oYxLiveAddressEntity.getApplyId());
        oLiveApplyUpdateWrapper.set("live_state", 4);
        oYxLiveApplyMapper.update(null, oLiveApplyUpdateWrapper);
        oYxLiveCostMapper.insert(oYxLiveCostEntity);
        oYxVideoCoinEntity.setLiveCostId(oYxLiveCostEntity.getLiveCostId());
        oVideoCoinMapper.insert(oYxVideoCoinEntity);        
        oShopMapper.updateById(oYxLiveShopEntity);
        oYxLiveAddressMapper.updateById(oYxLiveAddressEntity);
        //oLivePushStreamRedisCacheVO.setLiveState(LiveStateEnum.LIVE_END.getCode());
        final String liveShopId = oYxLiveAddressEntity.getLiveShopId().toString();
        redisTemplate.executePipelined((RedisCallback<Object>) new RedisCallback<Object>() 
        {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                // 这里逻辑简单不会抛异常
                // 否则需要加上try...catch...finally防止链接未正常关闭 造成泄漏
                connection.openPipeline();
                try
                { 
                    String redisKeyTmp = LiveShopConstant.LIVE_PUSH_STREAM_CACHE_REDISKEY_PREFIX.concat(liveId);
                    connection.set(redisTemplate.getKeySerializer().serialize(redisKeyTmp),redisTemplate.getValueSerializer().serialize(oLivePushStreamRedisCacheVO));
                    connection.expire(redisTemplate.getKeySerializer().serialize(redisKeyTmp), expireTime);
                    connection.set(redisTemplate.getKeySerializer().serialize(LiveShopConstant.LIVE_SHOP_ONLINELIVE_STATE_CHECK_PREFIX.concat(liveId)),redisTemplate.getValueSerializer().serialize(LiveStateEnum.LIVE_END.getCode()));
                    connection.expire(redisTemplate.getKeySerializer().serialize(LiveShopConstant.LIVE_SHOP_ONLINELIVE_STATE_CHECK_PREFIX.concat(liveId)), expireTime);
                    connection.hDel(redisTemplate.getKeySerializer().serialize(LiveShopConstant.LIVE_SHOP_ONLINELIVE_HASH_REDISKEY), redisTemplate.getHashKeySerializer().serialize(liveId));
                    connection.hDel(redisTemplate.getKeySerializer().serialize(LiveShopConstant.LIVE_SHOP_ONLINELIVE_SHOPIDKEY_HASH_REDISKEY), redisTemplate.getHashKeySerializer().serialize(liveShopId));           
                }
                catch(Exception e)               
                {
                    log.error("clientSendEndPushApply命令异常:====================================>{}", e);
                    throw new BaseException("clientSendEndPushApply命令异常:"+e.getMessage());
                }
                finally
                {
                    connection.close();
                }
                // executePipelined源码要求RedisCallback必须返回null，否则抛异常
                return null;
            }
        }); 
         //可能不存在，所以没有加入批量操作
        oRedisManager.delMapValue(LiveShopConstant.LIVE_SHOP_MANAGER_ADDVIRTUALVISITOR_HASHMAP_KEY.concat(liveId), liveId);
        //redisKey = LiveShopConstant.LIVE_SHOP_ONLINELIVE_HASH_REDISKEY;
        //oRedisManager.delMapValue(redisKey,oYxLiveAddressEntity.getId());
        LiveEndShowInforVO oLiveEndShowInforVO = new LiveEndShowInforVO();
        oLiveEndShowInforVO.setLiveId(liveId);
        oLiveEndShowInforVO.setLiveTotallDuration(oLivePushStreamRedisCacheVO.getTotallPushDuration().toString());
        oLiveEndShowInforVO.setLiveTotallWatchCount(totallWatchCount.toString());
        oLiveEndShowInforVO.setLiveTotallWatchUserCount(totallWatchUserCount.toString());
        oLiveEndShowInforVO.setLiveTotallFee(orderTotallFee.toString());
        return BaseResult.success(oLiveEndShowInforVO);
    }
    /**
     * 服务器端检查异常结束推流的直播
     * @param 
     * @return BaseResult
     */
    @Transactional(rollbackFor = Exception.class)
    public BaseResult serverEndLive(String liveId,LivePushStreamRedisCacheVO oLiveRedisCacheVO)
    {
        //YxLiveAddressEntity oYxLiveAddressEntity =  oYxLiveAddressMapper.selectById(liveId);
        String redisKey = LiveShopConstant.LIVE_ADDRESS_REDISKEY_PREFIX.concat(liveId);
        YxLiveAddressEntity oYxLiveAddressEntity = (YxLiveAddressEntity)oRedisManager.get(redisKey);
        if(null == oYxLiveAddressEntity)
        {
            oYxLiveAddressEntity =  oYxLiveAddressMapper.selectById(liveId);
            if(null == oYxLiveAddressEntity)
            {
                return BaseResult.failed("200", "Id对应的直播不存在");
            }
        }
        redisKey = LiveShopConstant.LIVE_PUSH_STREAM_CACHE_REDISKEY_PREFIX.concat(liveId);
        //LivePushStreamRedisCacheVO oLiveRedisCacheVO = (LivePushStreamRedisCacheVO)oRedisManager.get(redisKey);
        if(null == oLiveRedisCacheVO)
        {
            return BaseResult.failed("从Redis缓存中找不到对应缓存数据");
        }
        BaseResult ratioBaseResult = billingSetupServiceClient.getFeeDeductRatio();
        Integer iRatio = 0;
        if(ratioBaseResult.isResult())
        {
            iRatio = (Integer)ratioBaseResult.getData();
        }
        else
        {
            return BaseResult.failed("200", "获取兑换率失败");
        }
        if(iRatio<1)
        {
            return BaseResult.failed("200", "兑换率不能小于1");
        }
        redisKey = LiveShopConstant.LIVE_SHOP_VISIT_TOTAL_USERMAP_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId());
        LinkedHashMap oTotallUsersLinkedHashMap = (LinkedHashMap)oRedisManager.getMap(redisKey);
        Long totallWatchUserCount = 0L;
        Long totallWatchCount = 0L;
        Long watchDuration = 0L;
        Long watchStreamLen = 0L;
        Long orderCount = 0L;
        Long orderTotallFee = 0L;
        Long maxOnlineUsersCount = 0L;
        Long expireTime = System.currentTimeMillis() - oYxLiveAddressEntity.getLiveEndTime()+ REDIS_CACHE_DELAY_TIME.intValue();
        List<String> redisKeys = new java.util.ArrayList(); 
        
        redisKeys.add(LiveShopConstant.LIVE_SHOP_VISIT_TOTAL_USER_COUNT_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()));
        redisKeys.add(LiveShopConstant.LIVE_SHOP_LIVE_TOTAL_WATCH_DURATION_LENGHT_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()));
        redisKeys.add(LiveShopConstant.LIVE_SHOP_LIVE_TOTAL_WATCH_STREAM_LENGHT_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()));
        redisKeys.add(LiveShopConstant.LIVE_SHOP_ORDER_TOTAL_COUNT_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()));
        redisKeys.add(LiveShopConstant.LIVE_SHOP_ORDER_TOTAL_FEE_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId())); 
        redisKeys.add(LiveShopConstant.LIVE_SHOP_ONLINE_USER_MAX_COUNT_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getId()));
        List<Object> oList = oRedisManager.multiGet(redisKeys);
        if(null != oList)
        {
            totallWatchCount = Long.valueOf(String.valueOf(oList.get(0)));
            watchDuration = Long.valueOf(String.valueOf(oList.get(1)));
            watchStreamLen = Long.valueOf(String.valueOf(oList.get(2)));
            orderCount = Long.valueOf(String.valueOf(oList.get(3)));
            orderTotallFee = Long.valueOf(String.valueOf(oList.get(4)));
            maxOnlineUsersCount = Long.valueOf(String.valueOf(oList.get(5)));
        }
        if(null != oTotallUsersLinkedHashMap)
        {
            totallWatchUserCount = Long.valueOf(oTotallUsersLinkedHashMap.size());
        }       
        oYxLiveAddressEntity.setPushStartServerTime(oLiveRedisCacheVO.getPushLogStartTime());
        oYxLiveAddressEntity.setPushEndServerTime(oLiveRedisCacheVO.getLastPushLogTime());
        oYxLiveAddressEntity.setPushStartTime(oLiveRedisCacheVO.getPushLogStartClientTime());
        oYxLiveAddressEntity.setPushEndTime(oLiveRedisCacheVO.getLastPushLogClientTime());
        oYxLiveAddressEntity.setLiveState(LiveStateEnum.LIVE_END.getCode());
        Integer liveFee;
        oYxLiveAddressEntity.setLiveTotallDuration(oLiveRedisCacheVO.getTotallPushDuration()/1000);
        liveFee = oYxLiveAddressEntity.getLiveTotallDuration().intValue()/iRatio/60;
        oYxLiveAddressEntity.setLiveFees(liveFee);
        oYxLiveAddressEntity.setLiveTotallPushLength(oLiveRedisCacheVO.getTotallPushLength());
        oYxLiveAddressEntity.setLiveOrderCount(orderCount.intValue());
        oYxLiveAddressEntity.setLiveOrderTotalFee(new BigDecimal(orderTotallFee));
        //oYxLiveAddressEntity.setWatchDuration(watchDuration);
        oYxLiveAddressEntity.setWatchStreamLength(watchStreamLen);
        oYxLiveAddressEntity.setWatchUserCount(totallWatchUserCount);
        oYxLiveAddressEntity.setWatchNumber(totallWatchCount);
        oYxLiveAddressEntity.setMaxOnlineUserCount(maxOnlineUsersCount); 
        LiveEndShowTotallInforVO oLiveEndShowTotallInforVO = getLiveEndShowTotallInfor(oYxLiveAddressEntity);
        oYxLiveAddressEntity.setWatchDuration(oLiveEndShowTotallInforVO.getWatchDuration());
        oYxLiveAddressEntity.setAveragWatchDuration(oLiveEndShowTotallInforVO.getAveragWatchDuration());
        oYxLiveAddressEntity.setWatchUserPayRate(oLiveEndShowTotallInforVO.getWatchUserPayRate());
        oYxLiveAddressEntity.setAddedFansNumber(oLiveEndShowTotallInforVO.getAddedFansNumber());
        oYxLiveAddressEntity.setCommentNumber(oLiveEndShowTotallInforVO.getCommentNumber());
        oYxLiveAddressEntity.setCommentUserNumber(oLiveEndShowTotallInforVO.getCommentUserNumber());
        oYxLiveAddressEntity.setLikeNumber(oLiveEndShowTotallInforVO.getLikeNumber());        
        oYxLiveAddressEntity.setUpdateTime(BaseDateTime.getDate());
        oYxLiveAddressEntity.setProductNumber(oLiveEndShowTotallInforVO.getProductNumber());
        
        YxLiveShopEntity oYxLiveShopEntity = oShopMapper.selectById(oYxLiveAddressEntity.getLiveShopId());
        Integer feeRemainder = oYxLiveShopEntity.getLiveCoin().intValue()-liveFee;
        oYxLiveShopEntity.setLiveCoin(new BigDecimal(feeRemainder));
        oYxLiveShopEntity.setUpdateTime(BaseDateTime.getDate());
        YxVideoCoinEntity oYxVideoCoinEntity = new YxVideoCoinEntity();
        oYxVideoCoinEntity.setAmount("-" + liveFee);
        
        oYxVideoCoinEntity.setShopName(oYxLiveShopEntity.getShopName());
        oYxVideoCoinEntity.setShopId(oYxLiveShopEntity.getLiveShopId());
        oYxVideoCoinEntity.setShopkeeperId(oYxLiveShopEntity.getUserId());
        oYxVideoCoinEntity.setShopkeeperName(oYxLiveShopEntity.getUserName());
        oYxVideoCoinEntity.setType(0);
        oYxVideoCoinEntity.setDetail("直播 " + BaseDateTime.getLongDateTimeString(oYxLiveAddressEntity.getLiveEndTime()));
        oYxVideoCoinEntity.setTradingTime(BaseDateTime.getDate());
        oYxVideoCoinEntity.setTransactionNum(IdWorkerUtils.generateTransactionNumber());
        oYxVideoCoinEntity.setStatus(0);
        YxLiveCostEntity oYxLiveCostEntity = new YxLiveCostEntity();
        oYxLiveCostEntity.setStartTime(BaseDateTime.getDate(oLiveRedisCacheVO.getPushLogStartTime()));
        oYxLiveCostEntity.setEndTime(BaseDateTime.getDate(oLiveRedisCacheVO.getLastPushLogTime()));
        oYxLiveCostEntity.setLiveId(liveId);
        oYxLiveCostEntity.setShopId(oYxLiveAddressEntity.getLiveShopId());
        oYxLiveCostEntity.setTotalTime(oLiveRedisCacheVO.getTotallPushDuration().toString());
        oYxLiveCostEntity.setExpendVideoCoin(liveFee);
        oYxLiveCostEntity.setExpenditureTime(BaseDateTime.getDate());
        oYxLiveCostMapper.insert(oYxLiveCostEntity);
        oYxVideoCoinEntity.setLiveCostId(oYxLiveCostEntity.getLiveCostId());        
        oVideoCoinMapper.insert(oYxVideoCoinEntity);
        oShopMapper.updateById(oYxLiveShopEntity);
        oYxLiveAddressMapper.updateById(oYxLiveAddressEntity);
        //oLiveRedisCacheVO.setLiveState(LiveStateEnum.LIVE_END.getCode());
        //oRedisManager.set(redisKey, oLiveRedisCacheVO);
        //redisKey = LiveShopConstant.LIVE_SHOP_ONLINELIVE_HASH_REDISKEY;
        //oRedisManager.delMapValue(redisKey,oYxLiveAddressEntity.getId());
        final String liveShopId = oYxLiveAddressEntity.getLiveShopId().toString();
        redisTemplate.executePipelined((RedisCallback<Object>) new RedisCallback<Object>() 
        {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                // 这里逻辑简单不会抛异常
                // 否则需要加上try...catch...finally防止链接未正常关闭 造成泄漏
                connection.openPipeline();
                try
                { 
                    String redisKeyTmp = LiveShopConstant.LIVE_PUSH_STREAM_CACHE_REDISKEY_PREFIX.concat(liveId);
                    connection.set(redisTemplate.getKeySerializer().serialize(redisKeyTmp),redisTemplate.getValueSerializer().serialize(oLiveRedisCacheVO));
                    connection.expire(redisTemplate.getKeySerializer().serialize(redisKeyTmp), expireTime);
                    connection.set(redisTemplate.getKeySerializer().serialize(LiveShopConstant.LIVE_SHOP_ONLINELIVE_STATE_CHECK_PREFIX.concat(liveId)),redisTemplate.getValueSerializer().serialize(LiveStateEnum.LIVE_END.getCode()));
                    connection.expire(redisTemplate.getKeySerializer().serialize(LiveShopConstant.LIVE_SHOP_ONLINELIVE_STATE_CHECK_PREFIX.concat(liveId)), expireTime);
                    connection.hDel(redisTemplate.getKeySerializer().serialize(LiveShopConstant.LIVE_SHOP_ONLINELIVE_HASH_REDISKEY), redisTemplate.getHashKeySerializer().serialize(liveId));
                    connection.hDel(redisTemplate.getKeySerializer().serialize(LiveShopConstant.LIVE_SHOP_ONLINELIVE_SHOPIDKEY_HASH_REDISKEY), redisTemplate.getHashKeySerializer().serialize(liveShopId));
                }
                catch(Exception e)               
                {
                    log.error("serverEndLive命令异常:====================================>{}", e);
                    throw new BaseException("serverEndLive命令异常:"+e.getMessage());
                }
                finally
                {
                    connection.close();
                }
                // executePipelined源码要求RedisCallback必须返回null，否则抛异常
                return null;
            }
        });  
        //可能不存在，所以没有加入批量操作
        oRedisManager.delMapValue(LiveShopConstant.LIVE_SHOP_MANAGER_ADDVIRTUALVISITOR_HASHMAP_KEY.concat(liveId), liveId);
        return BaseResult.success();
    }      
    /**
     * 店铺获取推流地址
     * @param shopGetPushURLDTO
     * @return BaseResult
     */
    @Override
    public BaseResult shopGetPushURL(HttpServletRequest httpRequest,LiveShopGetPushURLDTO shopGetPushURLDTO)
    {
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed("没有操作权限");
        }
        if(!shopGetPushURLDTO.getUserId().equals(oBaseUserDTO.getUserId()))
        {
            return BaseResult.failed("没有操作权限");
        }
        YxLiveAddressEntity oYxLiveAddressEntity =  oYxLiveAddressMapper.selectById(shopGetPushURLDTO.getLiveId());     
        if(null == oYxLiveAddressEntity)
        {
            return BaseResult.failed("200", "Id对应的直播不存在");
        }        
        QueryWrapper<YxLiveShopEntity> oYxLiveShopQueryWrapper = new QueryWrapper();
        oYxLiveShopQueryWrapper.eq("shop_id",oYxLiveAddressEntity.getShopId());
        YxLiveShopEntity oYxLiveShopEntity = oShopMapper.selectOne(oYxLiveShopQueryWrapper);
        if(null == oYxLiveShopEntity)
        {
            return BaseResult.failed("200", "Id对应的店铺不存在");
        }
        QueryWrapper<YxLiveShopUserEntity> oYxLiveShopUserQueryWrapper = new QueryWrapper();
        oYxLiveShopUserQueryWrapper.eq("shop_id",oYxLiveAddressEntity.getShopId());
        oYxLiveShopUserQueryWrapper.eq("shop_user_id",shopGetPushURLDTO.getUserId());
        if(oYxLiveShopUserMapper.selectCount(oYxLiveShopUserQueryWrapper)<1)
        {
            return BaseResult.failed("200", "不是店铺员工,没有操作权限");
        }
        
        if(null != oYxLiveShopEntity.getLiveCoin())
        {
            if(oYxLiveShopEntity.getLiveCoin().intValue() < 10)
            {
                return BaseResult.failed("200","店铺的视频币(" + oYxLiveShopEntity.getLiveCoin() + ")即将耗尽，请先充值");
            }
        }
        if(oYxLiveShopEntity.getShopState() == 0)
        {
            return BaseResult.failed("200","店铺被禁止直播，请先申述解禁");
        }
        if(oYxLiveShopEntity.getShopState() == 1)
        {
            return BaseResult.failed("200","店铺被中断直播，请稍后再试");
        }        
        String appName = getDefaultAppName();
        if(appName.equals(""))
        {
            return BaseResult.failed("200","平台还没有配置appName");
        }
        YxLiveDomainEntity pushYxLiveDomainEntity = getPushDomain();
        if(null == pushYxLiveDomainEntity)
        {
            return BaseResult.failed("200","平台还没有配置推流域名");
        }
        if(StrUtil.isBlank(pushYxLiveDomainEntity.getDomainName()))
        {
            return BaseResult.failed("200","平台配置推流域名信息时没有配置域名关键字");
        }
        if(StrUtil.isBlank(pushYxLiveDomainEntity.getSecretKey()))
        {
            return BaseResult.failed("200","平台配置推流域名信息时没有配置密钥关键字");
        } 
       
        /*
        Long volcStartTime = System.currentTimeMillis() / 1000;
        Long volcTime =  volcStartTime + 86400;
        String  streamName = shopGetPushURLDTO.getShopId() + "_" +volcStartTime + "_" + UUID.randomUUID().toString().replaceAll("-", "");
        String sign = PasswordUtil.md5Hex("/" + appName + "/" + streamName + pushYxLiveDomainEntity.getSecretKey() + volcTime);
        //rtmp://yx-push.yxjt.vip/{AppName}/{StreamName}?{鉴权信息}
        String pushUrl = "rtmp://" + pushYxLiveDomainEntity.getDomainName() + "/" + appName + "/" + streamName + "?volcTime=" + volcTime + "&volcSecret=" + sign;
        
        Long now = System.currentTimeMillis();
        YxLiveShopPunishEntity oYxLiveShopPunishEntity = new YxLiveShopPunishEntity();
        QueryWrapper<YxLiveShopPunishEntity> oYxLiveShopPunishQueryWrapper = new QueryWrapper();
        oYxLiveShopPunishQueryWrapper.eq("shop_id",shopGetPushURLDTO.getShopId());
        oYxLiveShopPunishQueryWrapper.eq("punish_type",1);
        oYxLiveShopPunishQueryWrapper.lt("punish_time_start",now);
        oYxLiveShopPunishQueryWrapper.gt("punish_time_end",now);
        //oYxLiveShopPunishMapper.selectCount(oYxLiveShopPunishQueryWrapper); 
        if(oYxLiveShopPunishMapper.selectCount(oYxLiveShopPunishQueryWrapper) > 1)
        {
            return BaseResult.failed("200","店铺被禁止直播，请先申述解禁");
        }
        */
        //{鉴权信息}拼接格式为volcTime={UnixTime}&volcSecret=md5("/{AppName}/{StreamName}{SecretKey}{volcTime}")
        return BaseResult.success(oYxLiveAddressEntity.getPushUrl());
    }
     /**
     * 用户获取直播间播放地址
     * @param userGetPlayURLDTO
     * @return BaseResult
     */
    @Override
    public BaseResult userGetPlayURL(HttpServletRequest httpRequest,UserGetPlayURLDTO userGetPlayURLDTO)
    {
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }
        String token = httpRequest.getHeader("token");
        if(StrUtil.isBlank(token))
        {
            token = "";
        }
        //{鉴权信息}拼接格式为volcTime={UnixTime}&volcSecret=md5("/{AppName}/{StreamName}{SecretKey}{volcTime}")
        YxLiveAddressEntity oYxLiveAddressEntity = (YxLiveAddressEntity)oRedisManager.get(LiveShopConstant.LIVE_ADDRESS_REDISKEY_PREFIX.concat(userGetPlayURLDTO.getLiveId()));
        if(null == oYxLiveAddressEntity)
        {
            //oYxLiveAddressEntity =  oYxLiveAddressMapper.selectById(userGetPlayURLDTO.getLiveId());
            return BaseResult.failed("200", "直播已经结束");
        }
        //if(null == oYxLiveAddressEntity)
        //{
        //    return BaseResult.failed("200", "Id对应的直播不存在");
        //}
        String aesKey;
        token = userGetPlayURLDTO.getUserId().trim() + token.trim();
        if(token.length()<16)
        {
            aesKey = String.format("%016d", token);
        }
        else
        {
            aesKey = token.substring(0, 16);
        }
        String userPlayURL = (String)Aes128.Aes128EncryptUtf8(oYxLiveAddressEntity.getLiveUrl(), aesKey).getData();
        LiveOnlineInRedisCacheVO oLiveOnlineInRedisCacheVO = oYxLiveAddressEntity.ToLiveOnlineInRedisCacheVO();
        oLiveOnlineInRedisCacheVO.setLiveUrl(userPlayURL);
        return BaseResult.success(oLiveOnlineInRedisCacheVO);
    }    
     /**
     * 店铺查询直播
     * @param oShopSendLiveQueryDTO
     * @return BaseResult
     */
    @Override
    public BaseResult shopSendLiveQuery(HttpServletRequest httpRequest,ShopSendLiveQueryDTO oShopSendLiveQueryDTO)
    {
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }
        Page<YxLiveAddressEntity> pageParams = new Page<>(oShopSendLiveQueryDTO.getCurrPage(),oShopSendLiveQueryDTO.getPageSize());
        QueryWrapper<YxLiveAddressEntity> oYxLiveAddressQueryWrapper = new QueryWrapper();
        oYxLiveAddressQueryWrapper.eq(ObjectUtil.isNotEmpty(oShopSendLiveQueryDTO.getShopId()),"shop_id",oShopSendLiveQueryDTO.getShopId());
        oYxLiveAddressQueryWrapper.eq(ObjectUtil.isNotEmpty(oShopSendLiveQueryDTO.getLiveState()),"live_state",oShopSendLiveQueryDTO.getLiveState());
        oYxLiveAddressQueryWrapper.ge(ObjectUtil.isNotEmpty(oShopSendLiveQueryDTO.getStartCreateTime()),"create_time",oShopSendLiveQueryDTO.getStartCreateTime());
        oYxLiveAddressQueryWrapper.le(ObjectUtil.isNotEmpty(oShopSendLiveQueryDTO.getEndCreateTime()),"create_time",oShopSendLiveQueryDTO.getEndCreateTime());
        return BaseResult.success(PageUtils.get(oYxLiveAddressMapper.selectPage(pageParams, oYxLiveAddressQueryWrapper)));    
    }
    @Override
    public String getDefaultAppName()
    {
        if(null == appName)
        {
            appName = "";
        }
        if(appName.trim().equals(""))
        {
            YxLiveAppEntity oYxLiveAppEntity = new YxLiveAppEntity();
            QueryWrapper<YxLiveAppEntity> oYxLiveAppQueryWrapper = new QueryWrapper();
            oYxLiveAppQueryWrapper.gt("app_id",0);
            List<YxLiveAppEntity> oListYxLiveApp = oYxLiveAppMapper.selectList(oYxLiveAppQueryWrapper);
            if(!oListYxLiveApp.isEmpty())
            {
                appName = oListYxLiveApp.get(0).getAppName();
            }
        }
        return appName;
    }
    @Override
    public YxLiveDomainEntity getPushDomain()
    {
        if(null == pushDomainEntity)
        {
            QueryWrapper<YxLiveDomainEntity> oYxLiveDomainQueryWrapper = new QueryWrapper();
            oYxLiveDomainQueryWrapper.eq("domain_type",0);
            oYxLiveDomainQueryWrapper.eq("state",1);
            List<YxLiveDomainEntity> oListYxLiveDomain = oYxLiveDomainMapper.selectList(oYxLiveDomainQueryWrapper);
            if(!oListYxLiveDomain.isEmpty())
            {
                pushDomainEntity = oListYxLiveDomain.get(0);
            }            
        }
        return pushDomainEntity;
    }
    @Override
    public YxLiveDomainEntity getLiveDomain()
    {
        if(null == liveDomainEntity)
        {
            QueryWrapper<YxLiveDomainEntity> oYxLiveDomainQueryWrapper = new QueryWrapper();
            oYxLiveDomainQueryWrapper.eq("domain_type",1);
            oYxLiveDomainQueryWrapper.eq("state",1);
            List<YxLiveDomainEntity> oListYxLiveDomain = oYxLiveDomainMapper.selectList(oYxLiveDomainQueryWrapper);
            if(!oListYxLiveDomain.isEmpty())
            {
                liveDomainEntity = oListYxLiveDomain.get(0);
            }            
        }
        return liveDomainEntity;
    }
    /*** 
    * 获取正在生效的主播协议
    * @return List<YxLiveAgreementEntity>
    **/
    @Override
    public BaseResult selectActiveAgreement()
    {
        BaseResult oBaseResult;
        LiveAgreementVO oLiveAgreementVO = (LiveAgreementVO)oRedisManager.get(LiveConstant.LiveActiveAgreementRedisKey);
        if(null == oLiveAgreementVO)
        {
            oBaseResult = oLiveAgreementFeignClient.selectActiveAgreement();
            if(oBaseResult.isResult())
            {
                oLiveAgreementVO = (LiveAgreementVO)oBaseResult.getData();
                return BaseResult.success(oLiveAgreementVO);
            }
            else
            {
                return BaseResult.failed("还没有初始化主播协议");
            }
        }
        else
        {
            return BaseResult.success(oLiveAgreementVO);
        }
    }    
    /*** 
    * 新增店铺的商品
    * @param oYxLiveActivityProductsAddDTOList
    * @return BaseResult
    **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult liveActivityProductsInsert(HttpServletRequest httpRequest,YxLiveActivityProductsAddDTO oYxLiveActivityProductsAddDTOList)
    {
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }        
        //String redisKey = LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(oYxLiveActivityProductsAddDTOList.getLiveApplyId());
        YxLiveApplyEntity oYxLiveApplyEntity = oYxLiveApplyMapper.selectById(oYxLiveActivityProductsAddDTOList.getLiveApplyId());//(YxLiveApplyEntity)oRedisManager.get(redisKey);
        if(null == oYxLiveApplyEntity)
        {
            return BaseResult.failed("根据店铺Id找不到有效的直播申请");
        }
        if(oYxLiveApplyEntity.getLiveState() != LiveStateEnum.LIVE_FILED.getCode())
        {
            return BaseResult.failed("直播已经开始，不能添加商品");
        }
        if(oYxLiveApplyEntity.getLiveEndTime() < System.currentTimeMillis())
        {
            return BaseResult.failed("直播结束时间已到，不能添加商品");
        }
        YxLiveShopUserEntity oYxLiveShopUserEntity = null;
        String key = LiveShopConstant.LIVE_SHOP_USER_REDISKEY_PREFIX.concat(oYxLiveApplyEntity.getLiveShopId().toString());
        Object oObject = oRedisManager.getMapValue(key,oBaseUserDTO.getUserId());
        if(null != oObject)
        {
            oYxLiveShopUserEntity = (YxLiveShopUserEntity)oObject;//oRedisManager.getMapValue(key,oBaseUserDTO.getUserId());
        }
        if(null == oYxLiveShopUserEntity)
        {
            return BaseResult.failed("200", "不是店铺员工,没有操作权限");
        }
        if(oYxLiveShopUserEntity.getLiveShopId().longValue() != oYxLiveApplyEntity.getLiveShopId().longValue())
        {
            return BaseResult.failed("200", "店员所属店铺Id不等于申请的店铺Id,没有操作权限");
        }        
        QueryWrapper<YxLiveActivityProductsEntity> oActivityProductQueryWrapper = new QueryWrapper();
        oActivityProductQueryWrapper.eq("live_apply_id",oYxLiveActivityProductsAddDTOList.getLiveApplyId());
        Integer iCount =  oYxLiveActivityProductsMapper.selectCount(oActivityProductQueryWrapper);
        if(null == iCount)
        {
            iCount = 0;
        }
        System.out.println("liveActivityProductsInsert 产品数量:" + oYxLiveActivityProductsAddDTOList.getProductList().size());
        for(YxLiveActivityProductsEntity oYxLiveActivityProductsEntity : oYxLiveActivityProductsAddDTOList.getProductList())
        {
            //System.out.println("oYxLiveActivityProductsEntity.getLiveApplyId()：" + oYxLiveActivityProductsEntity.getLiveApplyId());
           // System.out.println("oYxLiveActivityProductsEntity.getProductId()：" + oYxLiveActivityProductsEntity.getProductId());
            QueryWrapper<YxLiveActivityProductsEntity> oQueryWrapper = new QueryWrapper();
            oQueryWrapper.eq("live_apply_id",oYxLiveActivityProductsEntity.getLiveApplyId());
            oQueryWrapper.eq("product_id",oYxLiveActivityProductsEntity.getProductId());
            Integer iCountInner =  oYxLiveActivityProductsMapper.selectCount(oQueryWrapper);
            if(null == iCountInner)
            {
                iCountInner = 0;
            }
            System.out.println("liveActivityProductsInsert 去重复查询:iCountInner：" + iCountInner);
            if(iCountInner < 1)
            {
                iCount = iCount + 1;
                //YxLiveActivityProductsEntity oYxLiveActivityProductsEntity = oYxLiveActivityProductsAddDTO.ConverToEntity();
                oYxLiveActivityProductsEntity.setLiveShopId(oYxLiveApplyEntity.getLiveShopId());
                oYxLiveActivityProductsEntity.setChannelCode(oYxLiveApplyEntity.getChannelCode());
                if(null == oYxLiveActivityProductsEntity.getPopupShowDuration())
                {
                    oYxLiveActivityProductsEntity.setPopupShowDuration(60);
                }
                oYxLiveActivityProductsEntity.setProductRemainderNumber(oYxLiveActivityProductsEntity.getProductNumber());
                if(null == oYxLiveActivityProductsEntity.getProductLivePrice())
                {
                    oYxLiveActivityProductsEntity.setProductLivePrice(oYxLiveActivityProductsEntity.getProductPrice());
                }
                oYxLiveActivityProductsEntity.setLiveId(oYxLiveApplyEntity.getLiveAddressId());
                oYxLiveActivityProductsEntity.setLiveApplyId(oYxLiveApplyEntity.getId());
                oYxLiveActivityProductsEntity.setProductOrder(iCount);
                oYxLiveActivityProductsEntity.setCreateTime(BaseDateTime.getDate());
                oYxLiveActivityProductsEntity.setUpdateTime(BaseDateTime.getDate());
                oYxLiveActivityProductsMapper.insert(oYxLiveActivityProductsEntity);            
            }
        }
        System.out.println("liveActivityProductsInsert 完成写入:iCount：" + iCount);
        //oYxLiveActivityProductsDTO.setActivityProductId(oYxLiveActivityProductsEntity.getActivityProductId());
        return BaseResult.success();
    }
    /*** 
    * 修改店铺的商品时长
    * @param oYxLiveActivityProductsEditShowDurationDTO
    * @return BaseResult
    **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult liveActivityProductsEditShowDuration(YxLiveActivityProductsEditShowDurationDTO oYxLiveActivityProductsEditShowDurationDTO)
    {
        //String redisKey = LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(oYxLiveActivityProductsEditShowDurationDTO.getLiveApplyId());
        //YxLiveApplyEntity oYxLiveApplyEntity = (YxLiveApplyEntity)oRedisManager.get(redisKey);//oYxLiveApplyMapper.selectById(oYxLiveActivityProductsEditOrderDTO.getLiveApplyId());
        YxLiveApplyEntity oYxLiveApplyEntity = oYxLiveApplyMapper.selectById(oYxLiveActivityProductsEditShowDurationDTO.getLiveApplyId());//(YxLiveApplyEntity)oRedisManager.get(redisKey);
        if(null == oYxLiveApplyEntity)
        {
            return BaseResult.failed("根据店铺Id找不到有效的直播申请");
        }
        if(oYxLiveApplyEntity.getLiveState() != LiveStateEnum.LIVE_FILED.getCode())
        {
            return BaseResult.failed("直播已经开始，不能修改商品");
        }
        if(oYxLiveApplyEntity.getLiveEndTime() < System.currentTimeMillis())
        {
            return BaseResult.failed("直播结束时间已到，不能修改商品");
        }        
        UpdateWrapper<YxLiveActivityProductsEntity> oUpdateWrapper = new UpdateWrapper();
        for(Long id : oYxLiveActivityProductsEditShowDurationDTO.getLiveProductIdList())
        {
            oUpdateWrapper.eq("activity_product_id", id);
            oUpdateWrapper.set("popup_show_duration", oYxLiveActivityProductsEditShowDurationDTO.getPopupShowDuration());
            oYxLiveActivityProductsMapper.update(null, oUpdateWrapper);
        }
        return BaseResult.success();
    }
    /*** 
    * 修改店铺商品的价格
    * @param oYxLiveActivityProductsEditLivePriceDTO
    * @return BaseResult
    **/
    @Override
    public BaseResult liveActivityProductsEditLivePrice(HttpServletRequest httpRequest,YxLiveActivityProductsEditLivePriceDTO oYxLiveActivityProductsEditLivePriceDTO)
    {
        if(null == oYxLiveActivityProductsEditLivePriceDTO.getAddProductNumber())
        {
            oYxLiveActivityProductsEditLivePriceDTO.setAddProductNumber(0);
        }
        if(oYxLiveActivityProductsEditLivePriceDTO.getAddProductNumber() < 0)
        {
            oYxLiveActivityProductsEditLivePriceDTO.setAddProductNumber(0);
        }
        if(null == oYxLiveActivityProductsEditLivePriceDTO.getProductLivePrice())
        {
            oYxLiveActivityProductsEditLivePriceDTO.setProductLivePrice(BigDecimal.ZERO);
        }
        if(oYxLiveActivityProductsEditLivePriceDTO.getProductLivePrice().compareTo(BigDecimal.ONE) < 0)
        {
            oYxLiveActivityProductsEditLivePriceDTO.setProductLivePrice(BigDecimal.ZERO);
        }
        if(oYxLiveActivityProductsEditLivePriceDTO.getProductLivePrice().compareTo(BigDecimal.ONE) < 0 && oYxLiveActivityProductsEditLivePriceDTO.getAddProductNumber() == 0)
        {
            return BaseResult.failed("产品价格和添加数量不能同时为空");
        }
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }
        YxLiveActivityProductsEntity oYxLiveActivityProductsEntity = oYxLiveActivityProductsMapper.selectById(oYxLiveActivityProductsEditLivePriceDTO.getLiveProductId());
        if(null == oYxLiveActivityProductsEntity)
        {
            return BaseResult.failed("根据产品Id找不到产品信息");
        }        
        String redisKey = LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(oYxLiveActivityProductsEditLivePriceDTO.getLiveApplyId());
        YxLiveApplyEntity oYxLiveApplyEntity = (YxLiveApplyEntity)oRedisManager.get(redisKey);//oYxLiveApplyMapper.selectById(oYxLiveActivityProductsEditOrderDTO.getLiveApplyId());
        //YxLiveApplyEntity oYxLiveApplyEntity = oYxLiveApplyMapper.selectById(oYxLiveActivityProductsEntity.getLiveApplyId());//(YxLiveApplyEntity)oRedisManager.get(redisKey);
        if(null == oYxLiveApplyEntity)
        {
            return BaseResult.failed("根据店铺Id找不到有效的直播申请");
        }
        if(oYxLiveApplyEntity.getLiveState() >= LiveStateEnum.LIVE_END.getCode())
        {
            return BaseResult.failed("直播已结束，不能修改商品");
        }
        if(oYxLiveApplyEntity.getLiveEndTime() < System.currentTimeMillis())
        {
            return BaseResult.failed("直播结束时间已到，不能修改商品");
        }   

        String key = LiveShopConstant.LIVE_SHOP_USER_REDISKEY_PREFIX.concat(oYxLiveActivityProductsEntity.getLiveShopId().toString());
        YxLiveShopUserEntity oYxLiveShopUserEntity = (YxLiveShopUserEntity)oRedisManager.getMapValue(key,oBaseUserDTO.getUserId());
        if(null == oYxLiveShopUserEntity)
        {
            return BaseResult.failed("200", "不是店铺员工,没有操作权限");
        }
        if(!oYxLiveShopUserEntity.getShopId().equals(oYxLiveActivityProductsEntity.getShopId()))
        {
            return BaseResult.failed("200", "不是店铺员工,没有操作权限");
        }
        //添加产品数量
        if(oYxLiveActivityProductsEditLivePriceDTO.getAddProductNumber() > 0)
        {
            redisKey = RedisIdConstant.PRODUCT_TOTAL_CNT + ":" + oYxLiveActivityProductsEntity.getProductId();
            String PRODUCT_TOTAL_CNT = String.valueOf(oRedisManager.get(key));
            Integer productCnt = Integer.valueOf(PRODUCT_TOTAL_CNT);
            if(productCnt < oYxLiveActivityProductsEditLivePriceDTO.getAddProductNumber())
            {
                return BaseResult.failed("200", "添加的产品数量大于库存数量，添加失败");
            }
            java.math.BigDecimal productNumber = oYxLiveActivityProductsEntity.getProductNumber().add(new BigDecimal(oYxLiveActivityProductsEditLivePriceDTO.getAddProductNumber()));
            oYxLiveActivityProductsEntity.setProductNumber(productNumber);
            productNumber = oYxLiveActivityProductsEntity.getProductRemainderNumber().add(new BigDecimal(oYxLiveActivityProductsEditLivePriceDTO.getAddProductNumber()));
            oYxLiveActivityProductsEntity.setProductRemainderNumber(productNumber);
        }
        
        String priceHistory = oYxLiveActivityProductsEntity.getProductDetail();
        if(StrUtil.isBlank(oYxLiveActivityProductsEntity.getProductDetail()))
        {
            oYxLiveActivityProductsEntity.setProductDetail("");
        }
        oYxLiveActivityProductsEntity.setProductDetail(oYxLiveActivityProductsEntity.getProductDetail().trim());
        if(oYxLiveActivityProductsEntity.getProductDetail().equals(""))
        {
            oYxLiveActivityProductsEntity.setProductDetail(oYxLiveActivityProductsEditLivePriceDTO.getProductLivePrice().toString());
        }
        else
        {
            oYxLiveActivityProductsEntity.setProductDetail(oYxLiveActivityProductsEntity.getProductDetail() + "," + oYxLiveActivityProductsEditLivePriceDTO.getProductLivePrice().toString());
        }
        UpdateWrapper<YxLiveActivityProductsEntity> oUpdateWrapper = new UpdateWrapper();
        oUpdateWrapper.eq("activity_product_id", oYxLiveActivityProductsEditLivePriceDTO.getLiveProductId());
        if(oYxLiveActivityProductsEditLivePriceDTO.getAddProductNumber() > 0)
        {
            oUpdateWrapper.set("product_detail", oYxLiveActivityProductsEntity.getProductDetail());
            oUpdateWrapper.set("product_live_price", oYxLiveActivityProductsEditLivePriceDTO.getProductLivePrice());
        }
        if(oYxLiveActivityProductsEditLivePriceDTO.getProductLivePrice().compareTo(BigDecimal.ONE) > 0)
        {
            oUpdateWrapper.set("product_number", oYxLiveActivityProductsEntity.getProductNumber());
            oUpdateWrapper.set("product_remainder_number", oYxLiveActivityProductsEntity.getProductRemainderNumber());
        }
        oYxLiveActivityProductsMapper.update(null, oUpdateWrapper);
        redisKey = LiveShopConstant.LIVE_SHOP_PRODUCT_REDISKEY_PREFIX.concat(oYxLiveApplyEntity.getLiveAddressId());
        if(oRedisManager.exsistInHash(redisKey, oYxLiveActivityProductsEntity.getId().toString()))
        {
            oRedisManager.setMapValue(redisKey, oYxLiveActivityProductsEntity.getId().toString(), oYxLiveActivityProductsEntity);
        }
        return BaseResult.success();
    }
    /*** 
    * 修改店铺商品的排序序号
    * @param oYxLiveActivityProductsEditOrderDTO
    * @return BaseResult
    **/
    @Override
    public BaseResult liveActivityProductsEditOrder(YxLiveActivityProductsEditOrderDTO oYxLiveActivityProductsEditOrderDTO)
    {
        //String redisKey = LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(oYxLiveActivityProductsEditOrderDTO.getLiveApplyId());
        //YxLiveApplyEntity oYxLiveApplyEntity = (YxLiveApplyEntity)oRedisManager.get(redisKey);//oYxLiveApplyMapper.selectById(oYxLiveActivityProductsEditOrderDTO.getLiveApplyId());
        YxLiveApplyEntity oYxLiveApplyEntity = oYxLiveApplyMapper.selectById(oYxLiveActivityProductsEditOrderDTO.getLiveApplyId());//(YxLiveApplyEntity)oRedisManager.get(redisKey);
        if(null == oYxLiveApplyEntity)
        {
            return BaseResult.failed("根据店铺Id找不到有效的直播申请");
        }
        if(oYxLiveApplyEntity.getLiveState() != LiveStateEnum.LIVE_FILED.getCode())
        {
            return BaseResult.failed("直播已经开始，不能修改序号");
        }
        if(oYxLiveApplyEntity.getLiveEndTime() < System.currentTimeMillis())
        {
            return BaseResult.failed("直播结束时间已到，不能修改序号");
        }       
         
        Integer iCount ;
        List<YxLiveActivityProductsEntity> topProductList = new ArrayList();
        List<YxLiveActivityProductsEntity> nextProductList = new ArrayList();
        QueryWrapper<YxLiveActivityProductsEntity> oQueryWrapper = new QueryWrapper();
        oQueryWrapper.eq("live_apply_id",oYxLiveActivityProductsEditOrderDTO.getLiveApplyId());
        oQueryWrapper.orderByAsc("product_order");
        List<YxLiveActivityProductsEntity> list = oYxLiveActivityProductsMapper.selectList(oQueryWrapper);       
        if(!list.isEmpty())
        {
            Map<Long,Integer> oInMap = new java.util.HashMap();
            iCount = 1;
            for(Long id : oYxLiveActivityProductsEditOrderDTO.getLiveProductIdList())
            {
                oInMap.put(id, iCount);
                iCount = iCount + 1;
            }
            UpdateWrapper<YxLiveActivityProductsEntity> oUpdateWrapper = new UpdateWrapper();
            for(YxLiveActivityProductsEntity oYxLiveActivityProductsEntity : list)
            {
                Integer order = oInMap.get(oYxLiveActivityProductsEntity.getId());
                if(null != order)
                {
                    oYxLiveActivityProductsEntity.setProductOrder(order);
                    topProductList.add(oYxLiveActivityProductsEntity);
                    oUpdateWrapper.clear();
                    oUpdateWrapper.eq("activity_product_id", oYxLiveActivityProductsEntity.getId());
                    oUpdateWrapper.set("product_order", order);
                    oYxLiveActivityProductsMapper.update(null, oUpdateWrapper);                    
                }
                else
                {
                    nextProductList.add(oYxLiveActivityProductsEntity);
                }
            }
            for(YxLiveActivityProductsEntity oYxLiveActivityProductsEntity : nextProductList)
            {
                oYxLiveActivityProductsEntity.setProductOrder(iCount);
                oUpdateWrapper.clear();
                oUpdateWrapper.eq("activity_product_id", oYxLiveActivityProductsEntity.getId());
                oUpdateWrapper.set("product_order", iCount);
                oYxLiveActivityProductsMapper.update(null, oUpdateWrapper);
                topProductList.add(oYxLiveActivityProductsEntity);
                iCount = iCount + 1;
            }
        }
        topProductList.sort(Comparator.comparing(YxLiveActivityProductsEntity::getProductOrder));
        return BaseResult.success(topProductList);
    }
    /*** 
    * 删除店铺的商品
    * @param id
    * @return BaseResult
    **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult liveActivityProductsDeleteById(HttpServletRequest httpRequest,Long id)
    {
        if(ObjectUtil.isEmpty(id))
        {
            return BaseResult.failed("Id不能为空值");
        }
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }
        YxLiveActivityProductsEntity oYxLiveActivityProductsEntity = oYxLiveActivityProductsMapper.selectById(id);
        if(null == oYxLiveActivityProductsEntity)
        {
            return BaseResult.failed("根据产品Id找不到产品信息");
        }
        String key = LiveShopConstant.LIVE_SHOP_USER_REDISKEY_PREFIX.concat(oYxLiveActivityProductsEntity.getLiveShopId().toString());
        YxLiveShopUserEntity oYxLiveShopUserEntity = (YxLiveShopUserEntity)oRedisManager.getMapValue(key,oBaseUserDTO.getUserId());
        if(null == oYxLiveShopUserEntity)
        {
            return BaseResult.failed("200", "不是店铺员工,没有操作权限");
        }
        if(!oYxLiveShopUserEntity.getShopId().equals(oYxLiveActivityProductsEntity.getShopId()))
        {
            return BaseResult.failed("200", "不是店铺员工,没有操作权限");
        }
        oYxLiveActivityProductsMapper.deleteById(id);
        return BaseResult.success();
    }
    /*** 
    * 按列表删除店铺的商品 
    * @param oYxLiveActivityProductsAddDTOList
    * @return BaseResult
    **/
    @Override
    @Transactional(rollbackFor = Exception.class)    
    public BaseResult liveProductsDeleteList(HttpServletRequest httpRequest,YxLiveActivityProductsAddDTO oYxLiveActivityProductsAddDTOList)
    {
        //String redisKey = LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(oYxLiveActivityProductsAddDTOList.getLiveApplyId());
        //YxLiveApplyEntity oYxLiveApplyEntity = (YxLiveApplyEntity)oRedisManager.get(redisKey);//oYxLiveApplyMapper.selectById(oYxLiveActivityProductsAddDTOList[0].getLiveApplyId());
        YxLiveApplyEntity oYxLiveApplyEntity = oYxLiveApplyMapper.selectById(oYxLiveActivityProductsAddDTOList.getLiveApplyId());//
        if(null == oYxLiveApplyEntity)
        {
            return BaseResult.failed("直播已结束，不能删除商品");
        }
        if(oYxLiveApplyEntity.getLiveState() != LiveStateEnum.LIVE_FILED.getCode())
        {
            return BaseResult.failed("直播已经开始，不能删除商品");
        }
        List<Long> idList = new ArrayList();
        for(YxLiveActivityProductsEntity oYxLiveActivityProductsEntity : oYxLiveActivityProductsAddDTOList.getProductList())
        {
            idList.add(oYxLiveActivityProductsEntity.getId());
        }
        oYxLiveActivityProductsMapper.deleteBatchIds(idList);
        return BaseResult.success();
    }
    /*** 
    * 根据id查找店铺的商品
    * @param id
    * @return YxLiveActivityProductsEntity
    **/
    @Override
    public YxLiveActivityProductsEntity liveActivityProductsSelectById(Long id)
    {
        if(ObjectUtil.isEmpty(id))
        {
            return null;
        }
        return oYxLiveActivityProductsMapper.selectById(id);
    }
    /*** 
    * 自定义统计店铺的商品
    * @param oYxLiveActivityProductsQueryDTO
    * @return Integer
    **/
    @Override
    public Integer liveActivityProductsSelectCount(YxLiveActivityProductsQueryDTO oYxLiveActivityProductsQueryDTO)
    {
        QueryWrapper<YxLiveActivityProductsEntity> oYxLiveActivityProductsQueryWrapper = new QueryWrapper();
        oYxLiveActivityProductsQueryWrapper.eq(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getChannelCode()),"channel_code",oYxLiveActivityProductsQueryDTO.getChannelCode());
        oYxLiveActivityProductsQueryWrapper.eq(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getLiveShopId()),"live_shop_id",oYxLiveActivityProductsQueryDTO.getLiveShopId());
        oYxLiveActivityProductsQueryWrapper.eq(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getShopId()),"shop_id",oYxLiveActivityProductsQueryDTO.getShopId());
        oYxLiveActivityProductsQueryWrapper.eq(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getLiveApplyId()),"live_apply_id",oYxLiveActivityProductsQueryDTO.getLiveApplyId());
        oYxLiveActivityProductsQueryWrapper.eq(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getLiveApplyId()),"live_id",oYxLiveActivityProductsQueryDTO.getLiveId());
        oYxLiveActivityProductsQueryWrapper.like(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getProductName()),"product_name",oYxLiveActivityProductsQueryDTO.getProductName());
        oYxLiveActivityProductsQueryWrapper.ge(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getCreateTimeStart()),"create_time",oYxLiveActivityProductsQueryDTO.getCreateTimeStart());
        oYxLiveActivityProductsQueryWrapper.le(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getCreateTimeEnd()),"create_time",oYxLiveActivityProductsQueryDTO.getCreateTimeEnd());
        return oYxLiveActivityProductsMapper.selectCount(oYxLiveActivityProductsQueryWrapper);
    }
    /*** 
    * 自定义查询店铺的商品
    * @param oYxLiveActivityProductsQueryDTO
    * @return List<YxLiveActivityProductsEntity>
    **/
    @Override
    public List<LiveActivityProductsVO> liveActivityProductsSelectList(YxLiveActivityProductsQueryDTO oYxLiveActivityProductsQueryDTO)
    {
        QueryWrapper<YxLiveActivityProductsEntity> oYxLiveActivityProductsQueryWrapper = new QueryWrapper();
        oYxLiveActivityProductsQueryWrapper.eq(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getChannelCode()),"channel_code",oYxLiveActivityProductsQueryDTO.getChannelCode());
        oYxLiveActivityProductsQueryWrapper.eq(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getLiveShopId()),"live_shop_id",oYxLiveActivityProductsQueryDTO.getLiveShopId());
        oYxLiveActivityProductsQueryWrapper.eq(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getShopId()),"shop_id",oYxLiveActivityProductsQueryDTO.getShopId());
        oYxLiveActivityProductsQueryWrapper.eq(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getLiveApplyId()),"live_apply_id",oYxLiveActivityProductsQueryDTO.getLiveApplyId());
        oYxLiveActivityProductsQueryWrapper.eq(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getLiveId()),"live_id",oYxLiveActivityProductsQueryDTO.getLiveId());
        oYxLiveActivityProductsQueryWrapper.like(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getProductName()),"product_name",oYxLiveActivityProductsQueryDTO.getProductName());
        oYxLiveActivityProductsQueryWrapper.ge(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getCreateTimeStart()),"create_time",oYxLiveActivityProductsQueryDTO.getCreateTimeStart());
        oYxLiveActivityProductsQueryWrapper.le(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getCreateTimeEnd()),"create_time",oYxLiveActivityProductsQueryDTO.getCreateTimeEnd());   
        oYxLiveActivityProductsQueryWrapper.orderByAsc("live_apply_id","product_order");
        List<YxLiveActivityProductsEntity> oList = oYxLiveActivityProductsMapper.selectList(oYxLiveActivityProductsQueryWrapper);
        List<LiveActivityProductsVO> list = new ArrayList();
        for(YxLiveActivityProductsEntity oYxLiveActivityProductsEntity : oList)
        {
            list.add(oYxLiveActivityProductsEntity.ConvertToLiveActivityProductsVO());
        }
        return  list;
    }

    /*** 
    * 自定义分页查询店铺的商品
    * @param currentPage 当前页
    * @param pageSize 分页大小
    * @param oYxLiveActivityProductsQueryDTO
    * @return Page
    **/
    @Override
    public Page<LiveActivityProductsVO> liveActivityProductsSelectPage(int currentPage,int pageSize,YxLiveActivityProductsQueryDTO oYxLiveActivityProductsQueryDTO)
    {
        if(currentPage <= 1)
        {
            currentPage = 1;
        }
        if(pageSize <= 0)
        {
            pageSize = 10;
        }
        Page<YxLiveActivityProductsEntity> pageParams = new Page<>(currentPage,pageSize);
        QueryWrapper<YxLiveActivityProductsEntity> oYxLiveActivityProductsQueryWrapper = new QueryWrapper();
        oYxLiveActivityProductsQueryWrapper.eq(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getChannelCode()),"channel_code",oYxLiveActivityProductsQueryDTO.getChannelCode());
        oYxLiveActivityProductsQueryWrapper.eq(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getLiveShopId()),"live_shop_id",oYxLiveActivityProductsQueryDTO.getLiveShopId());
        oYxLiveActivityProductsQueryWrapper.eq(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getShopId()),"shop_id",oYxLiveActivityProductsQueryDTO.getShopId());
        oYxLiveActivityProductsQueryWrapper.eq(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getLiveApplyId()),"live_apply_id",oYxLiveActivityProductsQueryDTO.getLiveApplyId());
        oYxLiveActivityProductsQueryWrapper.eq(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getLiveApplyId()),"live_id",oYxLiveActivityProductsQueryDTO.getLiveId());
        oYxLiveActivityProductsQueryWrapper.like(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getProductName()),"product_name",oYxLiveActivityProductsQueryDTO.getProductName());
        oYxLiveActivityProductsQueryWrapper.ge(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getCreateTimeStart()),"create_time",oYxLiveActivityProductsQueryDTO.getCreateTimeStart());
        oYxLiveActivityProductsQueryWrapper.le(ObjectUtil.isNotEmpty(oYxLiveActivityProductsQueryDTO.getCreateTimeEnd()),"create_time",oYxLiveActivityProductsQueryDTO.getCreateTimeEnd());
        oYxLiveActivityProductsQueryWrapper.orderByAsc("live_apply_id","product_order");
        List<YxLiveActivityProductsEntity> oList = oYxLiveActivityProductsMapper.selectPage(pageParams, oYxLiveActivityProductsQueryWrapper).getRecords();
        List<LiveActivityProductsVO> list = new ArrayList();
        for(YxLiveActivityProductsEntity oYxLiveActivityProductsEntity : oList)
        {
            list.add(oYxLiveActivityProductsEntity.ConvertToLiveActivityProductsVO());
        }
        Page<LiveActivityProductsVO> oPage = new Page<>(pageParams.getCurrent(),pageParams.getSize());
        oPage.setTotal(pageParams.getTotal());
        oPage.setRecords(list);
        return oPage;
    }
    /*** 
    * 订单扣减
    * @param applyId 申请Id
    * @param liveId 直播流Id
    * @param orderFeeDecr
    * @return BaseResult
    **/
    @Override
    public BaseResult liveOrderDecr(String applyId,String liveId,BigDecimal orderFeeDecr)
    {
        String redisLiveStateCheckKey = LiveShopConstant.LIVE_SHOP_ONLINELIVE_STATE_CHECK_PREFIX.concat(liveId);
        Integer liveState = (Integer)oRedisManager.get(redisLiveStateCheckKey);
        LivePushStreamRedisCacheVO oLivePushStreamRedisCacheVO= (LivePushStreamRedisCacheVO)oRedisManager.get(LiveShopConstant.LIVE_PUSH_STREAM_CACHE_REDISKEY_PREFIX.concat(liveId));
        YxLiveAddressEntity oYxLiveAddressEntity = null;//(YxLiveAddressEntity)oRedisManager.get(LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(liveId));
        //YxLiveApplyEntity oYxLiveApplyEntity = (YxLiveApplyEntity)oRedisManager.get(LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(applyId));
        oYxLiveAddressEntity = (YxLiveAddressEntity)oRedisManager.get(LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(liveId));
        if(null == oYxLiveAddressEntity)
        {
            oYxLiveAddressEntity = oYxLiveAddressMapper.selectById(liveId);
            if(null == oYxLiveAddressEntity)
            {
                return BaseResult.failed("根据Id找不到对应的直播");
            }
        }
        if (null == liveState)
        {
            liveState = oYxLiveAddressEntity.getLiveState();
        }         
        if(null == oLivePushStreamRedisCacheVO)
        {   
            oLivePushStreamRedisCacheVO = new LivePushStreamRedisCacheVO();
            oLivePushStreamRedisCacheVO.setLiveStartTime(oYxLiveAddressEntity.getLiveStartTime());
            oLivePushStreamRedisCacheVO.setLiveEndTime(oYxLiveAddressEntity.getLiveEndTime());
        }
        if(oLivePushStreamRedisCacheVO.getLiveEndTime() < System.currentTimeMillis() || liveState.equals(LiveStateEnum.LIVE_END.getCode()))
        {
            oYxLiveAddressEntity.setLiveOrderCount(oYxLiveAddressEntity.getLiveOrderCount() -1);
            oYxLiveAddressEntity.setLiveOrderTotalFee(oYxLiveAddressEntity.getLiveOrderTotalFee().divide(orderFeeDecr));
            UpdateWrapper<YxLiveAddressEntity> oUpdateWrapper = new UpdateWrapper();
            oUpdateWrapper.eq("live_id", liveId);
            oUpdateWrapper.set("live_order_count", oYxLiveAddressEntity.getLiveOrderCount());
            oUpdateWrapper.set("live_order_total_fee", oYxLiveAddressEntity.getLiveOrderTotalFee());
            oYxLiveAddressMapper.update(null, oUpdateWrapper);   
        }     
        else
        {
            redisTemplate.executePipelined((RedisCallback<Object>) connection ->
            {
                connection.openPipeline();
                try
                {
                    String redisKey = LiveShopConstant.LIVE_SHOP_ORDER_TOTAL_COUNT_REDISKEY_PREFIX.concat(liveId);
                    connection.decrBy(redisTemplate.getKeySerializer().serialize(redisKey), 1);
                    redisKey = LiveShopConstant.LIVE_SHOP_ORDER_TOTAL_FEE_REDISKEY_PREFIX.concat(liveId);
                    connection.decrBy(redisTemplate.getKeySerializer().serialize(redisKey), orderFeeDecr.longValue());
                }
                catch(SerializationException e)
                {
                    log.error("liveOrderDecr  redisTemplate.executePipelined命令异常:====================================>{}", e);
                    throw new BaseException("liveOrderDecr redisTemplate.executePipelined命令异常:"+e.getMessage());
                }
                finally
                {
                    connection.close();
                }
                return null;
            });             
            //oRedisManager.decrBy(LiveShopConstant.LIVE_SHOP_ORDER_TOTAL_COUNT_REDISKEY_PREFIX.concat(liveId), 1);
            //oRedisManager.decrBy(LiveShopConstant.LIVE_SHOP_ORDER_TOTAL_FEE_REDISKEY_PREFIX.concat(liveId),orderFeeDecr.longValue());
        }
        return BaseResult.success();
    }
    /*** 
    * 商品讲解
    * @param liveId 直播流Id
    * @param productid  产品id
    * @return BaseResult
    **/
    @Override    
    public BaseResult liveActivityProductExplanation(HttpServletRequest httpRequest,String liveId,Long productid)
    {
        MqttLiveCommentVo mqttVo = new MqttLiveCommentVo();
        mqttVo.setType(5);
        // 接收人ID
        mqttVo.setReceiverId(liveId);
        mqttVo.setSysTime(new Date());
        mqttVo.setContent(productid.toString());
        mqttGateway.sendToMqtt(MqttTopicEnum.LIVE_COMMENT_TOPIC.getTopic() + liveId, JsonUtils.toJson(mqttVo));
        return BaseResult.success();
    }
    /*** 
    * 取消商品讲解
    * @param liveId 直播流Id
    * @param productid  产品id
    * @return BaseResult
    **/
    @Override
    public BaseResult liveActivityProductCancelExplanation(HttpServletRequest httpRequest,String liveId,Long productid)
    {
        MqttLiveCommentVo mqttVo = new MqttLiveCommentVo();
        mqttVo.setType(6);
        // 接收人ID
        mqttVo.setReceiverId(liveId);
        mqttVo.setSysTime(new Date());
        mqttVo.setContent(productid.toString());
        mqttGateway.sendToMqtt(MqttTopicEnum.LIVE_COMMENT_TOPIC.getTopic() + liveId, JsonUtils.toJson(mqttVo));
        return BaseResult.success();
    }    
    private YxLiveShopApplyEntity getLiveShopApply(Long liveShopId)
    {
        //YxLiveShopApplyEntity oYxLiveShopApplyEntity = (YxLiveShopApplyEntity)oRedisManager.get(LiveShopConstant.LIVE_SHOP_APPLY_REDISKEY_PREFIX.concat(liveShopId.toString()));
        //if(null == oYxLiveShopApplyEntity)
        //{
            QueryWrapper<YxLiveShopApplyEntity> oYxLiveShopApplyQueryWrapper = new QueryWrapper();
            oYxLiveShopApplyQueryWrapper.eq("live_shop_id",liveShopId);
            YxLiveShopApplyEntity oYxLiveShopApplyEntity =  oYxLiveShopApplyMapper.selectOne(oYxLiveShopApplyQueryWrapper);
            /*
            if(null != oYxLiveShopApplyEntity)
            {
                oRedisManager.set(LiveShopConstant.LIVE_SHOP_APPLY_REDISKEY_PREFIX.concat(liveShopId.toString()), oYxLiveShopApplyEntity);
            }*/
        //} 
        return oYxLiveShopApplyEntity;
    }
    private YxLiveApplyEntity getLiveApply(Long liveShopId)
    {
        Date now = BaseDateTime.getDate();
        /*
        YxLiveApplyEntity oYxLiveApplyEntity = (YxLiveApplyEntity)oRedisManager.get(LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(shipId));
        if(null != oYxLiveApplyEntity)
        {
            if(now.after(BaseDateTime.getDate(oYxLiveApplyEntity.getLiveEndTime()/1000)))
            {
                if(oYxLiveApplyEntity.getLiveState() != LiveStateEnum.LIVE_END.getCode())
                {
                    UpdateWrapper<YxLiveApplyEntity> oUpdateWrapper = new UpdateWrapper();
                    oUpdateWrapper.eq("apply_id", oYxLiveApplyEntity.getId());
                    oUpdateWrapper.set("live_state", LiveStateEnum.LIVE_END.getCode());
                    oYxLiveApplyMapper.update(null, oUpdateWrapper);                    
                }
                oRedisManager.del(LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(shipId));
                oYxLiveApplyEntity = null;
            }
        }
        if(null == oYxLiveApplyEntity)
        { 
        */
            QueryWrapper<YxLiveApplyEntity> oYxLiveApplyQueryWrapper = new QueryWrapper();
            oYxLiveApplyQueryWrapper.eq("live_shop_id",liveShopId);
            //oYxLiveApplyQueryWrapper.ge("live_start_time",now);
            //oYxLiveApplyQueryWrapper.le("live_end_time",now);
            oYxLiveApplyQueryWrapper.lt("live_state",LiveStateEnum.LIVE_END.getCode());
            //List<YxLiveApplyEntity> oListYxLiveApply = oYxLiveApplyMapper.selectList(oYxLiveApplyQueryWrapper);
            //return Res.ok(oListYxLiveApply);
            YxLiveApplyEntity oYxLiveApplyEntity = oYxLiveApplyMapper.selectOne(oYxLiveApplyQueryWrapper); 
            
            if(null != oYxLiveApplyEntity)
            {
                Long applyEndTime = oYxLiveApplyEntity.getLiveEndTime() - System.currentTimeMillis();
                if(applyEndTime < 1000)
                {
                    oYxLiveApplyEntity.setLiveState(LiveStateEnum.LIVE_END.getCode());
                    UpdateWrapper<YxLiveApplyEntity> oUpdateLiveApplyWrapper = new UpdateWrapper();
                    oUpdateLiveApplyWrapper.eq("apply_id", oYxLiveApplyEntity.getId());
                    oUpdateLiveApplyWrapper.set("live_state", LiveStateEnum.LIVE_END.getCode());      
                    oYxLiveApplyMapper.update(null, oUpdateLiveApplyWrapper);
                    oYxLiveApplyEntity.setLiveState(LiveStateEnum.LIVE_END.getCode());
                    UpdateWrapper<YxLiveAddressEntity> oUpdateLiveAddressWrapper = new UpdateWrapper();
                    oUpdateLiveAddressWrapper.eq("live_id", oYxLiveApplyEntity.getLiveAddressId());
                    oUpdateLiveAddressWrapper.set("live_state", LiveStateEnum.LIVE_END.getCode());      
                    oYxLiveAddressMapper.update(null, oUpdateLiveAddressWrapper);
                    return null;
                }
                //oRedisManager.set(LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(oYxLiveApplyEntity.getId()), oYxLiveApplyEntity);
            }
            else
            {
                return oYxLiveApplyEntity;
            }
        //}
        return oYxLiveApplyEntity;
    }
    public static BaseUserDTO getBaseUserInfo(HttpServletRequest httpRequest)//,String userId
    {
        /*
        Enumeration e = httpRequest.getHeaderNames();
        while(e.hasMoreElements()){
            String value = (String)e.nextElement();//调用nextElement方法获得元素
            System.out.println(value);
        } 
        */
        String token = httpRequest.getHeader(CommonConstant.TOKEN);
        if(StrUtil.isBlank(token))
        {
            return null;
        }
        return TokenUtil.getBaseUserByToken(token);        
    }
    private YxLiveShopUserEntity getYxLiveShopUserEntity(Long liveShopId,String userId)
    {
        String key = LiveShopConstant.LIVE_SHOP_USER_REDISKEY_PREFIX.concat(liveShopId.toString());
        Object oObject = oRedisManager.getMapValue(key,userId);
        if(null != oObject)
        {
            return (YxLiveShopUserEntity)oObject;
        }
        return null;
    }
    private LiveEndShowTotallInforVO getLiveEndShowTotallInfor(YxLiveAddressEntity oYxLiveAddressEntity)
    {
        //互动:评论，点赞，粉丝
        if(null == oYxLiveAddressEntity.getPushStartServerTime())
        {
            oYxLiveAddressEntity.setPushStartServerTime(oYxLiveAddressEntity.getLiveStartTime());
        }
        if(null == oYxLiveAddressEntity.getPushEndServerTime())
        {
            oYxLiveAddressEntity.setPushEndServerTime(oYxLiveAddressEntity.getLiveEndTime());
        }
        LiveEndShowTotallInforVO oLiveEndShowTotallInforVO = new LiveEndShowTotallInforVO();
        LiveInteractiveDataQueryDTO oLiveInteractiveDataQueryDTO = new LiveInteractiveDataQueryDTO();
        oLiveInteractiveDataQueryDTO.setLiveId(oYxLiveAddressEntity.getId());
        oLiveInteractiveDataQueryDTO.setShopId(oYxLiveAddressEntity.getLiveShopId());
        oLiveInteractiveDataQueryDTO.setLiveStartTime(BaseDateTime.getDate(oYxLiveAddressEntity.getPushStartServerTime()));
        oLiveInteractiveDataQueryDTO.setLiveEndTime(BaseDateTime.getDate(oYxLiveAddressEntity.getPushEndServerTime()));
        LiveInteractiveDataVO oLiveInteractiveDataVO = oLiveCommentServiceImpl.getLiveInteractiveDataAfterLiveEnd(oLiveInteractiveDataQueryDTO);        
        oLiveEndShowTotallInforVO.setAddedFansNumber(oLiveInteractiveDataVO.getAddedFansNumber());
        oLiveEndShowTotallInforVO.setCommentNumber(oLiveInteractiveDataVO.getLiveCommentNumber());
        oLiveEndShowTotallInforVO.setCommentUserNumber(oLiveInteractiveDataVO.getLiveCommentUserNumber());
        oLiveEndShowTotallInforVO.setLikeNumber(oLiveInteractiveDataVO.getLiveLikeNumber());
        //订单
        oLiveEndShowTotallInforVO.setLiveOrderCount(oYxLiveAddressEntity.getLiveOrderCount());
        oLiveEndShowTotallInforVO.setLiveOrderTotalFee(oYxLiveAddressEntity.getLiveOrderTotalFee());
        oLiveEndShowTotallInforVO.setWatchUserCount(oYxLiveAddressEntity.getWatchUserCount());
        if(oYxLiveAddressEntity.getLiveOrderCount() > 0 && oLiveEndShowTotallInforVO.getWatchUserCount().intValue() > 0)
        {
            BigDecimal OrderTotalUser = new BigDecimal(oYxLiveAddressEntity.getWatchUserCount());
            BigDecimal WatchUserPayRate = new BigDecimal(oLiveEndShowTotallInforVO.getLiveOrderCount());
            WatchUserPayRate = WatchUserPayRate.setScale(4).divide(OrderTotalUser);
            oLiveEndShowTotallInforVO.setWatchUserPayRate(WatchUserPayRate);
        }
        else
        {
            oLiveEndShowTotallInforVO.setWatchUserPayRate(BigDecimal.ZERO);
        }
        /*
        LambdaQueryWrapper<YxOrderEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(YxOrderEntity::getBussId, oYxLiveAddressEntity.getId());
        queryWrapper.eq(YxOrderEntity::getOrderStatus, 3);
        List<YxOrderEntity> orderEntitieList = oOrderMapper.selectList(queryWrapper);
        if(orderEntitieList.isEmpty())
        {
            oLiveEndShowTotallInforVO.setLiveOrderCount(0);
            oLiveEndShowTotallInforVO.setLiveOrderTotalFee(BigDecimal.ZERO);
            oLiveEndShowTotallInforVO.setWatchUserPayRate(BigDecimal.ZERO);
        }
        else
        {
            BigDecimal OrderTotalFee = BigDecimal.ZERO;
            for(YxOrderEntity OYxOrderEntity : orderEntitieList)
            {
                OrderTotalFee = OrderTotalFee.add(OYxOrderEntity.getActualAmount());
            }
            oLiveEndShowTotallInforVO.setLiveOrderCount(orderEntitieList.size());
            oLiveEndShowTotallInforVO.setLiveOrderTotalFee(OrderTotalFee);
            BigDecimal WatchUserPayRate = new BigDecimal(oLiveEndShowTotallInforVO.getLiveOrderCount());
            OrderTotalFee = new BigDecimal(oYxLiveAddressEntity.getWatchUserCount());
            WatchUserPayRate = WatchUserPayRate.setScale(4).divide(OrderTotalFee);
            oLiveEndShowTotallInforVO.setWatchUserPayRate(WatchUserPayRate);
        }
        */
        //观看时长
        String liveId = oYxLiveAddressEntity.getId();
        LiveWatchLogSumVO oLiveWatchLogSumVO = oYxLiveWatchLogMapper.getliveWatchDuration(liveId);
        if(null == oLiveWatchLogSumVO)
        {
            oLiveEndShowTotallInforVO.setWatchDuration(0L);
            oLiveEndShowTotallInforVO.setAveragWatchDuration(0L);
        }
        else
        {
            if(oLiveWatchLogSumVO.getDuration().intValue() == 0)
            {
                oLiveEndShowTotallInforVO.setWatchDuration(0L);
                oLiveEndShowTotallInforVO.setAveragWatchDuration(0L);
            }
            else
            {
                oLiveEndShowTotallInforVO.setWatchDuration(oLiveWatchLogSumVO.getDuration());
                oLiveEndShowTotallInforVO.setAveragWatchDuration(oLiveWatchLogSumVO.getDuration()/oYxLiveAddressEntity.getWatchUserCount());
            }        
        }
        //产品
        oYxLiveAddressEntity.setProductNumber(BigDecimal.ZERO);
        LinkedHashMap oOnlineProductLinkedHashMap = (LinkedHashMap)oRedisManager.getMap(LiveShopConstant.LIVE_SHOP_PRODUCT_REDISKEY_PREFIX.concat(liveId)); 
        if(!oOnlineProductLinkedHashMap.isEmpty()){
            
            List<LiveActivityProductsVO> listOnlineAll = Lists.newArrayList(oOnlineProductLinkedHashMap.values());
            for(LiveActivityProductsVO oLiveActivityProductsVO : listOnlineAll)
            {
                oYxLiveAddressEntity.setProductNumber(oLiveActivityProductsVO.getProductNumber().add(oYxLiveAddressEntity.getProductNumber()));
            }
        }
        oLiveEndShowTotallInforVO.setProductNumber(oYxLiveAddressEntity.getProductNumber());
        return oLiveEndShowTotallInforVO;
    }
    /*** 
    * 管理员结束直播
    * @param QueryStringIdDTO
    * @return int
    **/
    @Override
    public BaseResult shopManagerEndLive(HttpServletRequest httpRequest,ShopManagerEndLiveDTO oShopManagerEndLiveDTO)
    {
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }
        String redisKey = LiveShopConstant.LIVE_ADDRESS_REDISKEY_PREFIX.concat(oShopManagerEndLiveDTO.getLiveId());
        Object oObject = oRedisManager.get(redisKey);
        YxLiveAddressEntity oYxLiveAddressEntity = null;//(YxLiveAddressEntity)oRedisManager.get(redisKey);
        if(null != oObject)
        {
            oYxLiveAddressEntity = (YxLiveAddressEntity)oObject;
        }
        if(null == oYxLiveAddressEntity)
        {
            return BaseResult.failed("根据直播Id找不到直播缓存信息");
        }
        redisKey = LiveShopConstant.LIVE_SHOP_USER_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getLiveShopId().toString());
        YxLiveShopUserEntity oYxLiveShopUserEntity = (YxLiveShopUserEntity)oRedisManager.getMapValue(redisKey,oBaseUserDTO.getUserId()); 
        if(null == oYxLiveShopUserEntity)
        {
            return BaseResult.failed("不是店铺员工，没有操作权限");
        }
        MqttLiveCommentVo mqttVo = new MqttLiveCommentVo();
        mqttVo.setType(7);
        // 接收人ID
        mqttVo.setReceiverId(oShopManagerEndLiveDTO.getLiveId());
        mqttVo.setSysTime(new Date());
        mqttVo.setContent(oYxLiveShopUserEntity);
        mqttGateway.sendToMqtt(MqttTopicEnum.LIVE_COMMENT_TOPIC.getTopic() + oShopManagerEndLiveDTO.getLiveId(), JsonUtils.toJson(mqttVo));
        return BaseResult.success();    
    }
    /*** 
    * 管理员添加虚拟人数
    * @param QueryStringIdDTO
    * @return int
    **/
    @Override
    public BaseResult shopManagerAddVirtualVisitor(HttpServletRequest httpRequest,ShopManagerAddVirtualVisitorDTO oShopManagerAddVirtualVisitorDTO)
    {
        BaseUserDTO oBaseUserDTO = getBaseUserInfo(httpRequest);
        if(null == oBaseUserDTO)
        {
            return BaseResult.failed(NOT_LOGIN_ERROR_MSG);
        }
        String redisKey = LiveShopConstant.LIVE_ADDRESS_REDISKEY_PREFIX.concat(oShopManagerAddVirtualVisitorDTO.getLiveId());
        YxLiveAddressEntity oYxLiveAddressEntity =(YxLiveAddressEntity)oRedisManager.getT(redisKey);
        if(null == oYxLiveAddressEntity)
        {
            return BaseResult.failed("根据直播Id找不到直播缓存信息");
        }
        redisKey = LiveShopConstant.LIVE_SHOP_USER_REDISKEY_PREFIX.concat(oYxLiveAddressEntity.getLiveShopId().toString());
        YxLiveShopUserEntity oYxLiveShopUserEntity = (YxLiveShopUserEntity)oRedisManager.getMapValue(redisKey,oBaseUserDTO.getUserId()); 
        if(null == oYxLiveShopUserEntity)
        {
            return BaseResult.failed("不是店铺员工，没有操作权限");
        }  
        redisKey = LiveShopConstant.LIVE_SHOP_MANAGER_ADDVIRTUALVISITOR_HASHMAP_KEY;
        String mapKey = oYxLiveAddressEntity.getId();
        oRedisManager.setMapValue(redisKey, mapKey, oShopManagerAddVirtualVisitorDTO.getAddNumber());
        return BaseResult.success();
    }
    /*** 
    * 系统管理员添加虚拟人数
    * @param QueryStringIdDTO
    * @return int
    **/
    @Override
    public BaseResult systemManagerAddVirtualVisitor(HttpServletRequest httpRequest,ShopManagerAddVirtualVisitorDTO oShopManagerAddVirtualVisitorDTO)
    {

        String redisKey = LiveShopConstant.LIVE_ADDRESS_REDISKEY_PREFIX.concat(oShopManagerAddVirtualVisitorDTO.getLiveId());
        YxLiveAddressEntity oYxLiveAddressEntity =(YxLiveAddressEntity)oRedisManager.getT(redisKey);
        if(null == oYxLiveAddressEntity)
        {
            return BaseResult.failed("根据直播Id找不到直播缓存信息");
        }

        redisKey = LiveShopConstant.LIVE_SHOP_MANAGER_ADDVIRTUALVISITOR_HASHMAP_KEY;
        String mapKey = oYxLiveAddressEntity.getId();
        oRedisManager.setMapValue(redisKey, mapKey, oShopManagerAddVirtualVisitorDTO.getAddNumber());
        return BaseResult.success();
    }    
}
